考虑这个类和可变成员函数:
class foo
{
public:
template<class C, class... Cs>
void add(C&& c, Cs&&... cs)
{
...
add(cs...);
}
private:
void add(){ }
};
有没有办法将终止递归的空add
重载放在另一个范围内请忽略这是否是一个好主意,我只是在严格询问如何做到这一点,如果有的话我想把它放在impl
命名空间中,如下所示:
namespace impl
{
void add() {}
}
class foo
{
public:
template<class C, class... Cs>
void add(C&& c, Cs&&... cs)
{
...
using namespace impl;
add(cs...);
}
};
但上述代码在安装时不起作用。编译器抱怨在参数包为空时找不到与add
匹配的函数调用。
有没有一种方法可以使用一些范围技巧来实现这一点?
如何使用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...);
}
};
你可以这样做:
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...);
}
};
如果foo_impl
被放置在一个单独的命名空间中,这也会起作用。
但是,不能将它作为一个免费函数与add()
一起使用。在该语言中,成员函数和自由函数可以属于同一重载集的唯一上下文是在重载运算符查找期间。这是因为名称查找规则以及重载解析只能在名称查找之后进行,并且只能在该名称查找找到的函数集上进行。