6

g++ 似乎接受autodecltype(auto)作为初始和尾随返回类型的任何组合:

int a;
auto f() { return (a); }                             // int
auto g() -> auto { return (a); }                     // int
auto h() -> decltype(auto) { return (a); }           // int&
decltype(auto) i() { return (a); }                   // int&
decltype(auto) j() -> auto { return (a); }           // int
decltype(auto) k() -> decltype(auto) { return (a); } // int&

但是,clang 拒绝jandk说:错误:具有尾随返回类型的函数必须指定返回类型“auto”,而不是“decltype(auto)”演示)。

哪个编译器是正确的?在每种情况下应使用哪个规则(auto或)?在trailing-return-typedecltype(auto)中使用占位符类型是否有意义?

4

2 回答 2

14

auto引入尾随返回类型时需要。

§8.3.5 [dcl.fct] /2

在有表格的声明T DD

D1 ( parameter-declaration-clause)cv-qualifier-seq选择 ref-qualifier选择 exception-specification选择 attribute-specifier-seq选择 trailing-return-type

并且声明中包含的declarator-id的类型T D1是“derived -declarator-type-list T ”,

T应为单个类型说明符auto。[...]

有关与 [dcl.spec.auto]/1 的明显矛盾,另请参见核心问题 1852

于 2014-06-17T11:58:08.273 回答
3

在@Xeo建设性意见后编辑:

看来这个问题是由于标准草案的两处矛盾造成的。

根据标准草案§ 7.1.6.4 auto specifier [dcl.spec.auto]:

1类型说明符指定一个占位符类型auto,稍后将被替换,或者通过从初始化程序中推导,或者通过带有尾随返回类型的显式说明。auto 类型说明符也用于表示 lambda 是通用 lambda。decltype(auto)

2占位符类型可以与 decl-specifier-seq、type-specifier-seq、conversion-function-id 或trailing-return-type中的函数声明符一起出现,在此类声明符有效的任何上下文中。如果函数声明符包含一个 trailing-return-type (8.3.5),它指定了函数声明的返回类型。 如果函数声明的返回类型包含占位符类型,则函数的返回类型是从函数体中的返回语句推导出来的,如果有的话。

对上述内容的唯一解释表明 Clang 存在错误。

但是,由于核心问题 1852指定上述与第 8.3.5/2 节功能 [dcl.fct]相矛盾,因此应予以更改。问题的状态为准备就绪,这表明更改已被接受。

因此,GCC 有一个应该报告的错误。

于 2014-06-17T10:03:00.903 回答