Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing specific class name in different namespaces (SFINAE?)

Assume I have several classes with the same name in different namespaces.

namespace A { class Foo { ... }; }
namespace B { class Foo { ... }; }
namespace C { class Foo { ... }; }

I'd like to detect in compile-time if class named Foo despite namespace. For example some SFINAE class,

template <typename T> struct is_Foo {
  static const bool value = /* some magic here */;
}; 

Then I want is_Foo<A::Foo>::value was true, is_Foo<B::Foo>::value was true and is_Foo<A::Bar>::value was false.

Then, I'd like to use is_Foo in static_assert or std::enable_if. Is it possible?

like image 390
Oleg Svechkarenko Avatar asked Feb 13 '23 11:02

Oleg Svechkarenko


1 Answers

template <typename T>
struct is_Foo : public std::false_type {
};

template <>
struct is_Foo<A::Foo> : public std::true_type {
};

template <>
struct is_Foo<B::Foo> : public std::true_type {
};

template <>
struct is_Foo<C::Foo> : public std::true_type {
};

This works by making is_Foo<T> inherit from std::true_type for specializations of the T as A::Foo etc. and inherit from std::false_type for any other T. As you can see no SFINAE is used, just inheritance and template specialization.

This can be used for static_assert and enable_if.


If you don't want to specialize is_Foo for every class, you must make the classes 'cooperate', as suggested in the comments. One way of doing that is create a class and make all those classes inherit that class. That class can have either a special member you could check for or just you could check if T is_base_of that class.

like image 98
bolov Avatar answered Feb 16 '23 02:02

bolov