构造函数的类定义之外的默认参数,gcc 与 clang

问题描述 投票:0回答:3

代码如下:

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)的角度来看,谁是正确的?

注:

我也喜欢 clang 的选择,但是我要向 gcc 和 Visual Studio 报告 bug, 如果从标准角度来看这不正确,这有助于 说服编译器的开发人员解决这个问题。

海湾合作委员会

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

但不幸的是,他们暂停了错误修复,直到草案成为标准。 演示

c++ visual-c++ gcc c++11 clang++
3个回答
12
投票

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

来自邮件列表讨论:

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

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

第 21 工作组在布卢明顿会议上最后讨论了这一问题。笔记来自 那里:

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

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

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


1
投票

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

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

将默认值添加到构造函数的唯一参数中肯定可以不带参数地调用它,从而使其成为默认值。另外,8.3.6 说(强调我的):

默认参数表达式应在中指定only 参数声明子句 函数声明 <...>


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.