ADL in case of equal-named member function
As you found out yourself, adding a member function frobnicate
to the class interface of Bar
(or Bar<T>
in the template case), will prevent ADL from finding foo::frobnicate
.
The easiest -and in this case idiomatic- way to add frobnicate
functionality to a class Bar
(or to a class template Bar<T>
) is to add a non-member function frobnicate(Bar)
(or function template frobnicate(Bar<T>)
) to the namespace bar
namespace foo {
struct Foo {};
void frobnicate(Foo const &) {}
}
namespace bar {
template<class T>
struct Bar {
T t;
};
template<class T>
void frobnicate(Bar<T> const& b)
{
frobnicate(b.t);
}
}
int main () {
bar::Bar<foo::Foo> x;
frobnicate(x);
frobnicate(foo::Foo());
}
If you insist on having a member function, you will have to rename it to something like do_frobnicate()
. I would not use type traits tricks to get the same behavior as it is an indirect approach, and makes the class interfaces much harder to understand (remember Stroustrup's motto: "represent your ideas directly in code").