g ++似乎接受auto
和decltype(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拒绝j
和k
,说:错误:带尾随返回类型的函数必须指定返回类型' auto&#39 ;, not' decltype (自动)' (demonstration)。
哪个编译器正确?在每种情况下应使用哪个规则(auto
或decltype(auto)
)?在 trailing-return-type 中使用占位符类型是否有意义?
答案 0 :(得分:14)
auto
。
§8.3.5[dcl.fct] / 2
在声明
T D
中D
的格式为
D1 (
parameter-declaration-clause
)cv-qualifier-seq
optref-qualifier
optexception-specification
optattribute-specifier-seq
opttrailing-return-type
并且声明
T D1
中包含的 declarator-id 的类型是“derived- declarator-type-listT
”,
T
应为单个类型说明符自动。 [...]
另见Core Issue 1852与[dcl.spec.auto] / 1明显矛盾。
答案 1 :(得分:3)
在@Xeo建设性意见之后进行修改:
这个问题似乎是草案标准的两个地方之间的矛盾。
根据标准草案§7.1.6.4自动说明符[dcl.spec.auto]:
1
auto
和decltype(auto)
类型说明符指定一个占位符类型,稍后将替换它,可以通过从初始化程序中扣除,也可以通过显式指定具有尾随返回类型。自动类型说明符 也用来表示lambda是一个普通的lambda。
2
占位符类型可以在decl-specifier-seq,type-specifier-seq中带有函数声明符, 在此类声明符有效的任何上下文中,conversion-function-id或 trailing-return-type 。如果功能 declarator包含一个trailing-return-type(8.3.5),它指定函数的声明返回类型。 如果函数的声明返回类型包含占位符类型,则函数的返回类型为 从函数体中的return语句中推导出来,如果有的话。
对上述内容的唯一解释是,Clang有一个错误。
但是,由于core issue 1852指定上述与§8.3.5/ 2函数[dcl.fct] 相矛盾,因此应予以更改。问题的状态已经准备就绪,表明这些变化已被接受。
因此,海湾合作委员会有一个应该报告的错误。