У вашего "трюка" есть одна большая проблема.Попробуйте позвонить is_in_Family1(make_pair(Family1::ModelA(), Family2::ModelC())
, и вы увидите, что возвращаем true
, потому что ADL будет искать оба пространства имен ModelA
и ModelC
(из-за pair<ModelA, ModelC>
).
Игнорирование этой проблемы, сиспользуя ваши функции, это просто.
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 ){}
};
Это вызывает Bar
в зависимости от того, находится ли он в family2 или 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); }
};
У этого также есть общий запасной вариант.И ваш код имел неопределенное поведение, потому что вы использовали зарезервированное имя.Не используйте _T
.