【问题标题】:Program with "noexcept" constructor accepted by gcc, rejected by clanggcc接受的带有“noexcept”构造函数的程序,被clang拒绝
【发布时间】:2015-06-11 13:12:00
【问题描述】:

代码:

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 的复杂代码时遇到了这个问题。在该代码中,ST 是模板类;因此行为取决于实例化 S 的类型。对于某些类型,Clang 会因为此错误而拒绝它,而 g++ 允许它,并且 SFINAE 基于 is_constructible 和类似特征工作。

【问题讨论】:

  • 因为在 S 构造函数中,您会调用 T 构造函数,这可能会引发任何异常。我相信 Clang 是正确的
  • @SeverinPappadeux 关于异常是正确的,但问题似乎是代码是否应该立即被拒绝,或者= default 的效果是否应该定义为已删除 g++ 似乎在做什么。

标签: c++ c++11 gcc clang noexcept


【解决方案1】:

取决于您所咨询的标准版本。

N3337 [dcl.fct.def.default]/p2:

一个显式默认的函数 [...] 可能有一个显式的 exception-specification 仅当它与隐式声明中的 exception-specification 兼容 (15.4) 时。

这会使您的原始代码格式错误。

CWG issue 1778 将其更改为 (N4296 [dcl.fct.def.default]/p3):

如果一个显式默认的函数被声明为 exception-specification 与隐式声明上的异常规范不兼容 (15.4),则

  • 如果函数在其第一个声明中明确默认,则将其定义为已删除;
  • 否则,程序格式不正确。

这意味着构造函数现在仅仅被定义为删除。 (上述措辞合并了 N4285 所做的更改,这是一篇 C++14 后的论文,进行了一些清理更改,旨在纯粹是编辑性的。N3936 版本基本相同。)

大概是 GCC 实现了 CWG1778 的决议,而 Clang 没有。

【讨论】:

  • 哪个版本出现在已发布的 C++14 中? (clang 3.7 仍然拒绝带有 -std=c++14 的代码)
  • @MattMcNabb 这个问题的状态是“C++14”,所以第二个版本应该是C++14。请注意,这是一个 DR,因此即使在 C++11 模式下也可能会实现。
  • @MattMcNabb 4296 几乎是被选为 C++14 模错字之类的
  • @SeverinPappadeux Nah,4296 有一些 C++1z 的东西。我可能应该引用 3936 或 4140。
  • @T.C.谢谢,不知道。我认为是 4296 是因为官方标准标记为 2014 年 12 月 15 日(?)
猜你喜欢
  • 2021-04-07
  • 1970-01-01
  • 2019-01-31
  • 2016-10-20
  • 2022-10-12
  • 1970-01-01
  • 2011-11-29
  • 1970-01-01
  • 2021-06-11
相关资源
最近更新 更多