转发C++ 0x中的所有构造函数

Nei*_*l G 17 c++ templates constructor c++11

在C++ 0x中转发所有父构造函数的正确方法是什么?

我一直这样做:

class X: public Super {
    template<typename... Args>
        X(Args&&... args): Super(args...) {}
};
Run Code Online (Sandbox Code Playgroud)

Joh*_*itb 41

在C++ 0x中有一种更好的方法

class X: public Super {
  using Super::Super;
};
Run Code Online (Sandbox Code Playgroud)

如果您声明一个完美转发模板,那么您的类型在重载分辨率方面会表现不佳.想象一下你的基类是可转换的,int并且存在两个打印出类的函数

class Base {
public:
  Base(int n);
};

class Specific: public Base {
public:
  template<typename... Args>
    Specific(Args&&... args);
};

void printOut(Specific const& b);
void printOut(std::string const& s);
Run Code Online (Sandbox Code Playgroud)

你打电话给它

printOut("hello");
Run Code Online (Sandbox Code Playgroud)

会叫什么?这是不明确的,因为Specific可以转换任何参数,包括字符数组.它不考虑现有的基类构造函数就这样做了.使用声明继承构造函数只声明使其工作所需的构造函数.

  • @ user643722:它被称为"继承构造函数",没有人实现它.不是GCC 4.7,即使在主干中也不是Clang,不是VC11,*nobody*. (6认同)
  • 请注意,此功能现在最终可在gcc 4.8中使用. (2认同)

Den*_*ose 5

如果你想要正确转发的话,我认为你需要这样做Super(std::forward<Args>(args)...). args有一个名字,所以我相信它会在rvalue引用之前绑定到常规引用.

但更重要的是,您不会以这种方式转发复制构造函数.编译器仍会为您生成一个,因为它不考虑模板构造函数.在提供的示例中,您没问题,因为无论如何编译器生成的只会调用父拷贝构造函数,这正是您想要的.如果在更复杂的情况下这不合适,那么你必须自己编写.

  • 因为如果它们中的任何一个都是右值引用(并且你正在调用的构造函数期望这样),那么尝试传递它们将导致问题,因为它们现在是左值引用(它们具有名称). (3认同)