C++1z 标准如何在模板函数声明中定义属性的正确位置?
How does C++1z standard define the correct location of attributes in a template function declaration?
我注意到 C++11 和 C++14 标准中的第 18.8/1 节在 <exception>
header 概要中包含以下声明:
[[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
),因此第二个版本需要无论如何被使用。但我想知道第一个是否也应该有效。
这个:
template <class T> [[noreturn]] void throw_with_nested(T&& t);
始终是唯一正确的选项。在语法上,产生式来自 [gram] 的各个部分:
template-declaration:
template
<
template-parameter-list >
declaration
declaration:
[...]
function-definition
[...]
function-definition:
attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
属性必须在 template <...>
介绍人之后。
这只是标准中的起草问题,由我们自己提交 Mr. Wakely。
我注意到 C++11 和 C++14 标准中的第 18.8/1 节在 <exception>
header 概要中包含以下声明:
[[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
),因此第二个版本需要无论如何被使用。但我想知道第一个是否也应该有效。
这个:
template <class T> [[noreturn]] void throw_with_nested(T&& t);
始终是唯一正确的选项。在语法上,产生式来自 [gram] 的各个部分:
template-declaration:
template
<
template-parameter-list>
declarationdeclaration:
[...]
function-definition
[...]function-definition:
attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body
属性必须在 template <...>
介绍人之后。
这只是标准中的起草问题,由我们自己提交 Mr. Wakely。