C++ 为什么';“我的编译器不承认”;债券()=违约&引用;?
请看这个代码C++ 为什么';“我的编译器不承认”;债券()=违约&引用;?,c++,c++11,C++,C++11,请看这个代码 class Bond { public: Bond(int payments_per_year, int period_lengths_in_months); Bond() = default; private: const int payments_per_year; const int period_length_in_months; }; int main() { Bond b
class Bond
{
public:
Bond(int payments_per_year, int period_lengths_in_months);
Bond() = default;
private:
const int payments_per_year;
const int period_length_in_months;
};
int main()
{
Bond b; // Error here
}
尝试编译时,我收到一个错误:
错误C2280:'Bond::Bond(void)':尝试引用已删除的函数“
这不是一个“规则3”违反,因为我已经添加了默认构造函数回来
为什么编译器不识别
Bond()=default;
?默认构造函数被抑制,因为存在需要显式初始化的常量成员
因此,由于该抑制,写入Bond()=default
不会重新引入默认构造函数
(通过删除类中的所有构造函数可以看到这种效果-仍然无法实例化ab
)
如果您从成员中删除常量
,则一切都会好起来;尽管另一种选择是为每个常量
成员提供一个大括号或相等的初始值设定项
const int payments_per_year = 2;
const int period_length_in_months = 6;
例如。另一个修复方法是在常量声明中指定默认值:
const int payments_per_year = {12};
这仍然可以被值构造函数覆盖,但允许默认构造函数继续
<>这也是一个非常灵活的方法来简化多个构造函数的例子。 < P>你受到C++标准草案(或C++ 11)的部分的影响,它表示: 如果:
…
-没有大括号或相等初始值设定项的const限定类型(或其数组)的任何非变量非静态数据成员都没有用户提供的默认构造函数,
解决问题的关键可能是短语不带大括号或相等的初始值设定项,因此,如果您提供大括号或相等的初始值设定项来解决问题,例如:
const int payments_per_year{12};
const int period_length_in_months{48};
不需要大括号,我们可以在语法中看到:
brace-or-equal-initializer:
= initializer-clause
braced-init-list
但是使用统一初始化有一些优点,比如使它值得使用它们
gcc和clang都为此提供了更有意义的诊断。有时在多个编译器上尝试您的代码会很有帮助,特别是如果您有这样一个最小的测试用例,例如,clang说:
warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
Bond() = default;
^
note: default constructor of 'Bond' is implicitly deleted because field 'payments_per_year' of const-qualified type 'const int' would not be initialized
const int payments_per_year;
^
...
“const int”中还有一个错误
未初始化const成员。
初始化常量成员时,不会再产生错误。三违反规则与问题无关,不管是否存在(默认值)构造函数。=默认值
ing一个特殊成员并不意味着它存在,而是意味着隐式成员已生成。如果隐式生成的成员不存在,则您将得到此结果。即使我们很可能从本例中引用的错误中识别编译器,但有任何问题“为什么我的编译器?”“指出哪个编译器以及它的哪个版本将大大受益。可能值得提交一份错误报告,但诊断可能更有意义。一些[统一初始化捕获最近出现的错误]示例(我们需要大括号吗?等于和大括号确实很奇怪。不确定它的实际含义。初始化器列表中的Init?无论如何:类内成员初始化器是–嗯–初始化器,初始化的语法规则适用。这意味着=或{}@PaulSanders不,您不需要大括号,但统一初始化有很多优点,例如使窄化转换格式错误,值得使用。请参阅下面的更新。@ShafikYaghmour:您可以保留大括号,但删除相等的大括号。@ShafikYaghmour:是的,这也是我更喜欢使用a的部分原因nswer(另一个是实际的标准报价)。