是一个继承的默认构造函数,也是用户定义的
Is an inherited default constructor also user-defined?
Clang文档巧妙地解释了
如果类或结构没有用户定义的默认构造函数,则C++不允许默认构造它的const实例这个([dcl.init],p9(
以下代码为Base
提供了这样一个用户定义的默认构造函数,但g++和Clang不同意Derived
的默认构造函数是否是用户定义的,尽管Derived
确实显式继承了所有Base
构造函数(使用新的C++11继承构造函数特性(
#include <iostream>
class Base
{
public:
Base(): b_(0) {} // look! user-defined default constructor
void print() const { std::cout << b_ << "n"; }
private:
int b_;
};
class Derived
:
public Base
{
using Base::Base; // does this constitute a user-defined default constructor?
};
int main()
{
Base const b;
b.print(); // 0 for g++ & CLang
Derived const d;
d.print(); // 0 for g++, Clang: "default initialization of an object of const type 'const Derived' requires a user-provided default constructor"
}
g++4.8很高兴地接受了这个代码,但Clang 3.3不接受。标准是怎么说的
注意:如果没有Base
的用户定义默认构造函数,g++4.8和Clang 3.3都不接受Base const b;
(例如g++4.7.2以前接受过(。假设g++知道该规则,我认为这意味着g++将Derived
的默认构造函数视为用户定义的。但Clang 3.3的想法并非如此。
UPDATE:根据@JesseGood关于0/1参数构造函数从不继承的回答,我尝试将Base
构造函数更改为
Base(int b = 0, void* = nullptr): b_(b) {}
但是它不能解决Clang错误。
Clang是正确的。
关于const实例的相关文章来自8.5p7:
如果程序调用的对象的默认初始化const限定的类型T,T应为具有用户提供的类类型默认构造函数。
由于Base(): b_(0) {}
是用户提供的,所以Base const b;
是可以的。
下一个重要部分是12.9p3:
对于继承的候选集合中的每个非模板构造函数构造函数,而不是没有参数的构造函数或复制/移动具有单个参数的构造函数,构造函数是使用相同的构造函数特性隐式声明,除非中有一个用户声明的构造函数具有相同的签名出现using声明的类
这里的重要部分是粗体文本。我相信这排除了您的情况,因为Base()
是一个没有参数的构造函数。这意味着Derived
没有用户提供的默认构造函数(尽管仍然隐式声明了一个(。
这也意味着,基类中的默认构造函数、复制构造函数和移动构造函数是从不继承的。
- 具有enable_if外部类原型的模板类构造函数定义
- 构造函数定义中类声明中的模板值
- C++中的继承和构造函数定义
- 如何使用模板化构造函数定义演绎指南?
- 构造函数定义C
- 不正确的成员构造函数定义
- 具有虚拟多重继承的构造函数定义
- C++谷歌测试在哪里放置测试夹具构造函数定义
- 模板类定义中的模板构造函数定义
- C++下面给出的代码中的构造函数定义差异
- 带继承的构造函数定义
- 无法访问构造函数定义之外的变量
- 调用构造函数定义中的函数后收到Segmentation Fault 11错误
- 将具有默认值的构造函数定义为组合对象的私有字段
- 防止重新定义构造函数定义的方法
- 继承构造函数-定义可移植的固定大小类型(C++)
- 在类的私有部分为复制构造函数定义原型如何防止类的复制
- 如何指定继承类的构造函数定义
- 了解默认移动构造函数定义
- 理解构造函数定义块的语法变化