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