具有 "noexcept" 构造函数的程序被 gcc 接受,被 clang 拒绝
Program with "noexcept" constructor accepted by gcc, rejected by clang
代码:
struct T { T() {} };
struct S
{
T t;
S() noexcept = default;
};
int main()
{
// S s;
}
g++ 4.9.2 接受这个没有错误或警告,但是 clang 3.6 和 3.7 报告第 7 行:
error: exception specification of explicitly defaulted default constructor does not match the calculated one
但是,如果行 S s;
没有被注释掉,g++ 4.9.2 现在会报告:
noex.cc: In function 'int main()':
noex.cc:12:7: error: use of deleted function 'S::S()'
S s;
^
noex.cc:7:5: note: 'S::S() noexcept' is implicitly deleted because its exception-specification does not match the implicit exception-specification ''
S() noexcept = default;
^
哪个编译器适合原始代码?
背景:
g++ 甚至允许将以下内容添加到 main
:
std::cout << std::is_constructible<S>::value << '\n';
输出 0
。我在使用 clang 编译一些大量使用模板、SFINAE 和 noexcept 的复杂代码时遇到了这个问题。在该代码中 S
和 T
是模板 类;所以行为取决于 S
实例化的类型。对于某些类型,Clang 拒绝它并出现此错误,而 g++ 允许它并且 SFINAE 基于 is_constructible
和类似特征工作。
取决于您所参考的标准版本。
N3337 [dcl.fct.def.default]/p2:
An explicitly-defaulted function [...] may have an explicit
exception-specification only if it is compatible (15.4) with the exception-specification on the implicit declaration.
这会导致您的原始代码格式错误。
这已被 CWG issue 1778 更改为 (N4296 [dcl.fct.def.default]/p3):
If a function that is explicitly defaulted is declared with an
exception-specification that is not compatible (15.4) with the exception specification on the implicit declaration, then
- if the function is explicitly defaulted on its first declaration, it is defined as deleted;
- otherwise, the program is ill-formed.
这意味着构造函数现在仅被定义为已删除。 (以上措辞包含 N4285 所做的更改,post-C++14 论文进行了一些纯编辑性的清理更改。N3936 版本实质上相同。)
大概 GCC 实现了 CWG1778 的决议,而 Clang 没有。
代码:
struct T { T() {} };
struct S
{
T t;
S() noexcept = default;
};
int main()
{
// S s;
}
g++ 4.9.2 接受这个没有错误或警告,但是 clang 3.6 和 3.7 报告第 7 行:
error: exception specification of explicitly defaulted default constructor does not match the calculated one
但是,如果行 S s;
没有被注释掉,g++ 4.9.2 现在会报告:
noex.cc: In function 'int main()':
noex.cc:12:7: error: use of deleted function 'S::S()'
S s;
^
noex.cc:7:5: note: 'S::S() noexcept' is implicitly deleted because its exception-specification does not match the implicit exception-specification ''
S() noexcept = default;
^
哪个编译器适合原始代码?
背景:
g++ 甚至允许将以下内容添加到 main
:
std::cout << std::is_constructible<S>::value << '\n';
输出 0
。我在使用 clang 编译一些大量使用模板、SFINAE 和 noexcept 的复杂代码时遇到了这个问题。在该代码中 S
和 T
是模板 类;所以行为取决于 S
实例化的类型。对于某些类型,Clang 拒绝它并出现此错误,而 g++ 允许它并且 SFINAE 基于 is_constructible
和类似特征工作。
取决于您所参考的标准版本。
N3337 [dcl.fct.def.default]/p2:
An explicitly-defaulted function [...] may have an explicit exception-specification only if it is compatible (15.4) with the exception-specification on the implicit declaration.
这会导致您的原始代码格式错误。
这已被 CWG issue 1778 更改为 (N4296 [dcl.fct.def.default]/p3):
If a function that is explicitly defaulted is declared with an exception-specification that is not compatible (15.4) with the exception specification on the implicit declaration, then
- if the function is explicitly defaulted on its first declaration, it is defined as deleted;
- otherwise, the program is ill-formed.
这意味着构造函数现在仅被定义为已删除。 (以上措辞包含 N4285 所做的更改,post-C++14 论文进行了一些纯编辑性的清理更改。N3936 版本实质上相同。)
大概 GCC 实现了 CWG1778 的决议,而 Clang 没有。