1

我注意到 C++11 和 C++14 标准中的第 18.8/1 节在<exception>标题概要中包含以下声明:

[[noreturn]] template <class T> void throw_with_nested(T&& t);

而在最新的 C++17 草案中,相同的声明显示为

template <class T> [[noreturn]] void throw_with_nested(T&& t);

这是否意味着属性的语法在 C++17 中发生了变化,或者只是前一行是一个已得到纠正的错误?在 7.6 和 14.5.6 中,我都找不到任何关于属性应该出现在哪里的明确描述。有人可以指出这是在哪里定义的吗?

实际上,MSVC 对第一个和第二个声明都很满意,而 g++ 和 clang 拒绝编译第一个版本(后者带有相当明确的error: an attribute list cannot appear here),所以无论如何都需要使用第二个版本。但我想知道第一个是否也应该有效。

4

1 回答 1

4

这:

template <class T> [[noreturn]] void throw_with_nested(T&& t);

永远是唯一正确的选择。从语法上讲,产生式来自 [gram] 的各个部分:

模板声明
    template < 模板参数列表 > 声明

声明
    [...]
    函数定义
    [...]

函数定义
    attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt function-body

属性必须在template <...>介绍人之后。


这只是标准中的一个起草问题,由我们自己的Mr. Wakely提交。

于 2017-03-10T18:03:33.470 回答