程序与“noexcept”构造函数由gcc接受,被clang拒绝 [英] Program with "noexcept" constructor accepted by gcc, rejected by clang

查看:1048
本文介绍了程序与“noexcept”构造函数由gcc接受,被clang拒绝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

代码:

  struct T {T(){}}; 

struct S
{
T t;

S()noexcept = default;
};

int main()
{
// S s;
}

g ++ 4.9.2接受这个没有错误或警告, 3.7报告第7行:

 错误:显式默认构造函数的异常规范与计算的不匹配

但是,如果 S s; 行未注释掉, g ++ 4.9.2现在报告:

  noex.cc:在函数'int main()'中:
noex。 cc:12:7:错误:使用已删除的函数'S :: S()'
S s;
^
noex.cc:7:5:注意:'S :: S()noexcept'被隐式删除,因为它的异常规范不匹配隐式异常规范
S()noexcept = default;
^

哪个编译器适合原始代码?






背景:



g ++甚至允许添加到

  std :: cout< std :: is_constructible< S> :: value<< '\\\
';输出 0

我遇到这个问题,当使用clang编译一些复杂的代码,大量使用模板,SFINAE和noexcept。在该代码 S T 是模板类;因此行为取决于 S 被实例化的类型。 Clang拒绝它与一些类型的这个错误,而g ++允许它和SFINAE基于 is_constructible 和类似的traits工作。



N3337 [dcl.fct.def.default] /

p2:


显式默认的函数[...]可能有一个明确的




这是由 CWG问题1778 (N4296 [dcl.fct.def.default] / p3):


如果一个明确默认的函数使用与隐式声明的异常规范不兼容(15.4)的
异常规范 p>


  • 如果函数在其第一个声明中显式默认,则定义为删除;


这意味着构造函数现在只被定义为已删除。 (上述措词包含 N4285 所做的更改, C ++ 14纸张做一些清理更改纯粹是编辑的N3936版本是基本一样的)



可能GCC实现CWG1778的分辨率,而Clang不' t。


The code:

struct T { T() {} };

struct S
{
    T t;

    S() noexcept = default;
};

int main()
{
//    S s;
}

g++ 4.9.2 accepts this with no errors or warnings, however clang 3.6 and 3.7 report for line 7:

error: exception specification of explicitly defaulted default constructor does not match the calculated one

However, if the line S s; is not commented out, g++ 4.9.2 now reports:

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;
     ^

Which compiler is right for the original code?


Background:

g++ even allows the following to be added to main:

std::cout << std::is_constructible<S>::value << '\n';

which outputs 0. I encountered this problem when using clang to compile some complicated code that made heavy use of templates, SFINAE and noexcept. In that code S and T are template classes; so the behaviour depends on which types S was instantiated with. Clang rejects it with this error for some types, whereas g++ permits it and the SFINAE works based on is_constructible and similar traits.

解决方案

Depends on the version of the standard you are consulting.

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.

which renders your original code ill-formed.

This was changed by CWG issue 1778 to read (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.

which means that the constructor is now merely defined as deleted. (The above wording incorporated changes made by N4285, a post-C++14 paper making some cleanup changes intended to be purely editorial. The N3936 version is substantively the same.)

Presumably GCC implements CWG1778's resolution, while Clang doesn't.

这篇关于程序与“noexcept”构造函数由gcc接受,被clang拒绝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆