I was wondering if it is possible to have ADL select the function template defined in the namespace of the class of one of the arguments (or in some other well defined place) in a situation when other function templates are visible. I have a motivating example that follows, and although I know the way around for that particular case (I discuss it below), the question in general seems to make sense.
I thought kind of cool to avoid using friend declarations but rather delegate work to methods, and thus came up with
namespace n
{
struct a
{
auto swap(a& a2) -> void;
};
auto swap(a& a1, a& a2) -> void
{
a1.swap(a2);
}
}
auto main(void) -> int
{
n::a a1, a2;
using std::swap;
swap(a1,a2); // use case 1
n::swap(a1,a2); // use case 2
}
So far, so good, both use cases work fine, but then, I added a second class with its own swap method and decided to save on boilerplate by turning the freestanding swap into a template:
namespace n
{
struct a
{
auto swap(a& a2) -> void;
};
struct b
{
auto swap(b& b2) -> void;
};
template<class T>
auto swap(T& t1, T& t2) -> void
{
t1.swap(t2);
}
}
auto main(void) -> int
{
n::a a1, a2;
using std::swap;
swap(a1,a2); // use case 1
n::swap(a1,a2); // use case 2
}
And here use case 1 breaks, the compiler complains about ambiguity with the std::swap
template. If one anticipates the problem, it is possible to define swap
functions rahter than methods (they will usually be friend, since they replace methods):
namespace n
{
struct a
{
friend auto swap(a& a1, a& a2) -> void;
};
struct b
{
friend auto swap(b& b1, b& b2) -> void;
};
}
Now everything works, so in the case of swap
it is just enough to remember to use friend functions rahter than methods, but how about the general case? Is there any hack, however dirty, that would let the compiler unambiguously select n::foo<a>
(or some other foo<a>
under our control) in a situation where other template<class T> foo
are visible, either in the global namespace or because of some using
clause, especially if the latter are not ours to modify?