在C ++ 0x中转发所有父构造函数的正确方法是什么?
我一直这样做:
class X: public Super {
template<typename... Args>
X(Args&&... args): Super(args...) {}
};
答案 0 :(得分:41)
这个
在C ++ 0x中有更好的方法class X: public Super {
using Super::Super;
};
如果您声明了一个完美转发模板,那么您的类型在重载分辨率方面会表现不佳。想象一下,你的基类可以从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);
你用
来调用它printOut("hello");
会叫什么?这是不明确的,因为Specific
可以转换任何参数,包括字符数组。它这样做而不考虑现有的基类构造函数。使用声明继承构造函数只声明使其工作所需的构造函数。
答案 1 :(得分:5)
如果您希望正确转发内容,我认为您需要Super(std::forward<Args>(args)...)
。 args
有一个名称,所以我相信它会在rvalue引用之前绑定到常规引用。
但更重要的是,您不会以这种方式转发复制构造函数。编译器仍会为您生成一个,因为它不考虑模板构造函数。在提供的示例中,您没问题,因为无论如何编译器生成的只会调用父拷贝构造函数,这正是您想要的。如果在更复杂的情况下这不合适,那么你必须自己编写。