有没有办法让编译器在选择候选者时包含来自外部作用域的函数?

Jen*_*nsB 3 c++ templates scope function

考虑这个类和可变成员函数:

class foo
{
public:
    template<class C, class... Cs>
    void add(C&& c, Cs&&... cs)
    {
        ...
        
        add(cs...);
    }
private:
    void add(){ }
};
Run Code Online (Sandbox Code Playgroud)

有没有办法将终止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...);
    }
};
Run Code Online (Sandbox Code Playgroud)

但上面的代码在启动时不起作用。add当参数包为空时,编译器抱怨找不到匹配的函数调用。

有没有办法使用一些范围黑客来实现这一目标?

Bri*_*ian 5

你可以这样做:

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...);
    }
};
Run Code Online (Sandbox Code Playgroud)

foo_impl如果放置在单独的命名空间中,这也将起作用。

add()但是,您不能使其作为免费功能使用。在该语言中,成员函数和自由函数可以属于同一重载集的唯一上下文是在重载运算符查找期间。这是因为名称查找规则以及重载解析只能在名称查找之后发生,并且只能在该名称查找找到的函数集上发生。


康桓瑋*_*康桓瑋 5

怎么样使用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...);
  }
};
Run Code Online (Sandbox Code Playgroud)