使用gcc接受的“noexcept”构造函数的程序,被clang拒绝

时间:2015-04-07 03:16:00

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

代码:

struct T { T() {} };

struct S
{
    T t;

    S() noexcept = default;
};

int main()
{
//    S s;
}

g ++ 4.9.2接受这个没有错误或警告,但第7行的第3.6和3.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和类似特征工作。

1 个答案:

答案 0 :(得分:17)

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

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

  

明确默认的函数[...]可能有明确的   异常规范只有在隐式声明中与异常规范兼容(15.4)时才会出现。

会使原始代码格式不正确。

CWG issue 1778更改了这一点(N4296 [dcl.fct.def.default] / p3):

  

如果使用a声明显式默认的函数   异常规范与隐式声明中的异常规范不兼容(15.4),然后

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

这意味着构造函数现在只被定义为已删除。 (上面的措辞包含了N4285所做的更改,这是一篇C ++之后的14篇论文,其中一些清理更改仅仅是编辑性的.N3936版本实质上是相同的。)

据推测,GCC实施了CWG1778的解决方案,而Clang则没有。