Consider this class and variadic member function:
class foo
{
public:
template<class C, class... Cs>
void add(C&& c, Cs&&... cs)
{
...
add(cs...);
}
private:
void add(){ }
};
Is there a way to place the empty add
overload that terminates the recursion inside another scope? Please ignore whether or not this is generally a good idea, I am strictly asking for how one could do it, if at all. I would like to place it inside an impl
namespace like so:
namespace impl
{
void add() {}
}
class foo
{
public:
template<class C, class... Cs>
void add(C&& c, Cs&&... cs)
{
...
using namespace impl;
add(cs...);
}
};
But the above code does not work when instatiated. The compiler complains that it can't find a matching function call for add
when the parameter pack is empty.
Is there a way to achieve this using some scope-hackery?
CodePudding user response:
How about using if constexpr
:
namespace impl { void add() {} }
class foo {
public:
template<class C, class... Cs>
void add(C&& c, Cs&&... cs)
{
if constexpr (sizeof...(Cs) == 0)
impl::add();
else
add(cs...);
}
};
CodePudding user response:
You can do it like this:
class foo_impl
{
protected:
void add() {}
};
class foo : private foo_impl
{
using foo_impl::add;
public:
template<class C, class... Cs>
void add(C&& c, Cs&&... cs)
{
add(cs...);
}
};
This will also work if foo_impl
is placed in a separate namespace.
However, you can't make it work with add()
as a free function. The only context in the language where member functions and free functions can belong to the same overload set is during overloaded operator lookup. This is because of the name lookup rules and the fact that overload resolution can only take place after name lookup, and only on the set of functions found by that name lookup.