代码如下:
struct Foo {
Foo(const char *);
};
Foo::Foo(const char *str = 0)
{
}
VS 2013和gcc 4.8.0接受此类代码, 而clang 3.3拒绝这样的代码:
错误:在重新声明时添加默认参数会使此构造函数成为默认构造函数
谁从标准(C ++ 03和C ++ 11)的观点来看是正确的?
注意:
我也喜欢clang的选择,但是我要向gcc和visual studio报告bug, 如果从标准的角度来看这不正确,这有助于 说服编译器的开发人员解决这个问题。
GCC
我在这里描述了问题:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58194
但没有运气,他们暂停修复错误,直到草案成为标准。
答案 0 :(得分:12)
这已在Clang mailinglist上讨论过,并已作为Defect Report核心问题1344提交。
来自邮件列表讨论:
这个想法是某些特殊成员的存在会影响核心 类类型的属性,例如它是POD还是平凡的 可复制。决定这些属性不应该需要整个程序 知识;能够从中推断它们对我们来说很重要 类定义。真正有问题的案例是转向 通过添加默认值将“普通”构造函数转换为复制或移动构造函数 参数,但IIRC引入了默认构造函数 有问题的。
修复是您应该将默认参数放在首字母中 声明构造函数。
这是WG21在布卢明顿会议上的最后一次讨论。来自的说明 有:
“共识:按照写作中的建议使这种形式不正确。核心 问题1344.优先级0,道格起草。“
因此,CWG(原则上)同意这应该是不正确的。
TL; DR 只要缺陷得到修复,Clang就是正确的(不确定是否只能在C ++ 14上正式发生,或者委员会的决定也可以在C ++上追溯完成11)
答案 1 :(得分:1)
我会说CLANG是对的。标准说(标准的新旧版本均为12.1.5):
类X的默认构造函数是类X的构造函数,可以在没有参数的情况下调用
将默认值添加到构造函数的唯一参数肯定可以在没有参数的情况下调用它,从而使其成为默认值。另外,8.3.6说(强调我的):
默认参数表达式应在中仅指定 参数声明子句 一个函数声明< ...>
答案 2 :(得分:0)
您有声明和定义。在您的声明中,您没有默认值,而在您的定义中,您有一个默认值。事实上,声明的签名与定义的签名非常相似,但不一样。我认为严格是一个好主意,所以我认为最好强制声明与定义相同。