I have a function in my namespace, ns::foo
, whose job is to dispatch an invocation of foo
using argument-dependent lookup:
namespace ns
{
template<typename T>
void foo(T x)
{
// call foo through ADL
foo(x);
}
}
I want clients to be able to call foo
without having to manually instantiate it, i.e.:
bar x;
ns::foo(x);
Not
ns::foo<bar>(x);
The problem of course is that ns::foo
is recursive if there is no better match for foo
than ns::foo
.
I don't wish to give ns::foo
a different name, so is there any way to remove it from the overload set inside itself?
If the foo
to where you want to dispatch is not in the ns
namespace, then this should work:
namespace helper
{
template<typename T>
void _foo(T x)
{
// call foo through ADL
foo(x);
}
}
namespace ns
{
template<typename T>
void foo(T x)
{
::helper::_foo(x);
}
}
The trick is that the call to foo
from _foo
will not consider ns::foo
, because it is not in an argument-dependent namespace. Unless the type of x
happens to be in ns
of course, but then you have a recursion by definition.
UPDATE: You have to put this code just after the definition of namespace ns
:
namespace ns
{
//your useful stuff here
}
namespace helper { /* template _foo */ }
namespace ns { /* template foo */ }
There is no recursion because the helper::_foo
function cannot call the template foo
because it is still not defined.