代码看起来像:
struct Foo {
Foo(const char *);
};
Foo::Foo(const char *str = 0)
{
}
字符串
VS 2013和gcc 4.8.0 accept这样的代码,而clang 3.3拒绝这样的代码:
错误:在重新声明时添加默认参数使此构造函数成为默认构造函数
从标准(C++03和C ++11)的Angular 来看,谁是正确的?
注意事项:
我也喜欢clang的选择,但我会向gcc和visual studio报告bug,如果从标准的Angular 来看这是不正确的,这有助于说服编译器的开发人员修复这个问题。
GCC
我在这里描述的问题:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58194
但是运气不好,他们暂停了bug修复,直到草案成为标准。
3条答案
按热度按时间ippsafx71#
这已在Clang mailinglist上进行了讨论,并已作为缺陷报告核心问题1344提交。
从邮件列表讨论:
这个想法是,某些特殊成员的存在会影响类类型的核心属性,比如它是POD还是普通可复制的。对于我们来说,能够从类定义中推导出它们是很重要的。真正有问题的情况是通过添加默认参数将“普通”构造函数转换为复制或移动构造函数,但是IIRC引入默认构造函数也是有问题的。
修复方法是将默认参数放在构造函数的初始声明中。
这是第21工作组在布卢明顿会议上最后一次讨论的问题。
“共识:按照文章中的建议,使其格式不正确。核心问题1344。优先级0,道格起草。”
因此,CWG同意(原则上)这应该是病态的。
TL;只要缺陷得到修复,DRClang就是正确的(不确定这是否只能在C14上正式发生,或者这样的委员会决定是否也可以在C11上追溯)
yquaqz182#
我会说CLANG是对的。标准说(12.1.5对于标准的旧版本和新版本):
类X的默认构造函数是类X的构造函数,可以在没有参数的情况下调用
将默认值添加到构造函数的唯一参数中肯定可以不带参数地调用它,从而使它成为默认值。此外,8.3.6说(强调我的):
bttbmeg03#
你有一个声明和一个定义。在你的声明中,你没有默认值,而在你的定义中,你有一个默认值。事实上,声明的签名与定义的签名非常相似,但又不相同。我相信严格是一个好主意,所以我相信最好强制声明与定义相同。