I'm using the following compile-time 'trick' (based on ADL) to create a function that is only valid/defined/callable by classes in the same namespace.
namespace Family1
{
struct ModelA{};
struct ModelB{};
template<typename T>
bool is_in_Family1(T const& t)
{
return true;
}
};
namespace Family2
{
struct ModelC{};
template<typename T>
bool is_in_Family2(T const& t)
{
return true;
}
};
Family1::ModelA mA;
Family2::ModelC mC;
is_in_Family1(mA); // VALID
is_in_Family1(mC); // ERROR
Now, I'd like to use this principle (or something similar) in order to produce a specialization of Foo::Bar
(below) for classes belonging to each of the namespaces e.g. Family1
.
// I would like to specialize the method template Bar for classes in Family1
// namespace; and another specialization for classes in Family2 namespace
struct Foo
{
template<typename T>
void Bar( T& _T ){}
};
For ease of maintenance and the large number of classes in each namespace, if possible, I'd like to perform this check without naming all the classes in a namespace.
Your "trick" has one big problem. Try calling is_in_Family1(make_pair(Family1::ModelA(), Family2::ModelC())
and you will see that return true
, because ADL will look into both the namespaces of ModelA
and ModelC
(because of pair<ModelA, ModelC>
).
Ignoring that problem, with using your functions it is straight forward.
template<typename T> struct int_ { typedef int type; };
struct Foo
{
template<typename T,
typename int_<decltype(is_in_Family1(*(T*)0))>::type = 0
>
void Bar( T& t ){}
template<typename T,
typename int_<decltype(is_in_Family2(*(T*)0))>::type = 0
>
void Bar( T& t ){}
};
That calls Bar
depending on whether it is in family2 or family1.
struct Foo
{
template<typename T,
typename int_<decltype(is_in_Family1(*(T*)0))>::type = 0
>
void Bar( T& t, long){}
template<typename T,
typename int_<decltype(is_in_Family2(*(T*)0))>::type = 0
>
void Bar( T& t, long){}
template<typename T>
void Bar( T& t, int) {}
template<typename T>
void Bar( T& t ) { return Bar(t, 0); }
};
That one has also a generic fallback. And your code had undefined behavior because you used a reserved name. Don't use _T
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With