19

代码如下:

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 报告错误,如果从标准的角度来看这是不正确的,这有助于说服编译器的开发人员修复这个问题。

海合会

我在这里描述了问题:http: //gcc.gnu.org/bugzilla/show_bug.cgi ?id=58194

但运气不好,他们暂停错误修复,直到草案成为标准。

4

3 回答 3

12

这已在Clang 邮件列表中进行了讨论,并已作为缺陷报告核心问题 1344 提交。

从邮件列表讨论:

这个想法是某些特殊成员的存在会影响类类型的核心属性,例如它是 POD 还是可简单复制。决定这些属性不应该需要整个程序的知识;能够仅从类定义中推断出它们对我们来说很重要。真正有问题的情况是通过添加默认参数将“普通”构造函数转变为复制或移动构造函数,但 IIRC 引入默认构造函数也是有问题的。

解决方法是您应该将默认参数放在构造函数的初始声明中。

这是 WG21 在布卢明顿会议上的最后一次讨论。那里的笔记:

“共识:按照文章中的建议使这个格式不正确。核心问题 1344。优先级 0,Doug 起草。”

因此,CWG(原则上)同意这应该是错误的。

TL;只要缺陷得到修复,Clang 博士就是正确的(不确定这是否只能在 C++14 中正式发生,或者此类委员会决定是否也可以在 C++11 上追溯完成)

于 2013-08-19T12:34:26.053 回答
1

我会说 CLANG 是对的。该标准说(标准的旧版本和新版本均为 12.1.5):

类 X 的默认构造函数是类 X 的构造函数,可以在没有参数的情况下调用

将默认值添加到构造函数的唯一参数肯定可以在没有参数的情况下调用它,从而使其成为默认值。此外,8.3.6 说(强调我的):

默认参数表达式只能函数声明<...>的参数声明子句中指定

于 2013-08-19T12:23:26.983 回答
0

你有一个声明和一个定义。在您的声明中,您没有默认值,而在您的定义中,您有默认值。事实上,声明的签名与定义的签名非常相似,但又不一样。我认为严格是一个好主意,所以我认为最好强制声明与定义相同。

于 2013-08-19T12:23:25.493 回答