c++ - 继承构造函数 vs 转发

标签 c++ c++11 inheriting-constructors

C++11 允许继承构造函数,从而可以避免大量样板文件,尤其是使用包装类之类的东西。但是,您似乎已经可以单独使用可变参数模板实现此功能。

class B
{
public:
 B(int){//do something}
 B(int, char){//do something}
};

使用继承构造函数:

class D : public B
{
public:
 using B::B; 
};

使用可变模板和转发:

class D : public B
{
public:
 template <typename...Args>
 D(Args&&... args) : B(std::forward<Args>(args)...)
 {
 }
};

虽然一致性(对于 using 以相同的方式对待构造函数和方法)和易用性是将继承的构造函数引入语言的很好的理由,但还有其他原因为什么第一个解决方案应该是比第二个更喜欢?我发现 CWG 文档(N1890N1898)都在讨论继承构造函数,只需注意以下内容并继续:

Little more than a historical accident prevents using this to work for a constructor as well as for an ordinary member function. Had a constructor been called “ctor” or “constructor” rather than being referred to by the name of their class, this would have worked. We propose this as the mechanism for inheriting constructors.

最佳答案

主要原因是完美转发并不完美。简单案例:

struct B {
    B(int* ) { .. }
};

现在考虑:

D d{0};

如果我们继承构造函数,这就可以正常工作。如果我们完美转发,我们将尝试构造 B(int ),因为 0 推导为 int,这是一个不不存在。失败!

其他失败案例包括大括号初始化、仅声明静态常量数据成员、重载函数和位域。

关于c++ - 继承构造函数 vs 转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27951191/

相关文章:

c++ - 是否可以使用模板参数的所有组合生成类型?

c++ - 如何使用 fmt 库格式化指针?

c++ - 图像处理中的并发设计

c++ - 创建全局 C++ 对象

c++ - 继承构造函数并提供新的重载 : no arguments base constructor seems to not participate in overload resolution

c++ - 默认情况下是否继承构造函数 noexcept(true)?

c++ - 继承构造函数仅部分起作用

c++ - big-endian 中的整数转换

c++ - std::atomic<struct> 是否使所有成员也是原子的?

c++ - 对 avr 端口地址的 constexpr 引用