问题
g++ appears to accept any combination of auto and decltype(auto) as initial and trailing return types:
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&
However, clang rejects j and k, saying: error: function with trailing return type must specify return type 'auto', not 'decltype(auto)' (demonstration).
Which compiler is correct? Which rule (auto or decltype(auto)) should be used in each case? And does it make any sense to use a placeholder type in a trailing-return-type?
回答1:
auto is required when introducing a trailing-return-type.
§8.3.5 [dcl.fct] /2
In a declaration
T DwhereDhas the form
D1 (parameter-declaration-clause)cv-qualifier-seqoptref-qualifieroptexception-specificationoptattribute-specifier-seqopttrailing-return-typeand the type of the contained declarator-id in the declaration
T D1is “derived-declarator-type-listT”,
Tshall be the single type-specifier auto. [...]
See also Core Issue 1852 for the apparent contradiction with [dcl.spec.auto]/1.
回答2:
Edit after @Xeo constructive comments:
It seems that this issue is due a contradiction between two places of the draft standard.
According to the draft standard § 7.1.6.4 auto specifier [dcl.spec.auto]:
1Theautoanddecltype(auto)type-specifiers designate a placeholder type that will be replaced later, either by deduction from an initializer or by explicit specification with a trailing-return-type. The auto type-specifier is also used to signify that a lambda is a generic lambda.
2The placeholder type can appear with a function declarator in the decl-specifier-seq, type-specifier-seq, conversion-function-id, or trailing-return-type, in any context where such a declarator is valid. If the function declarator includes a trailing-return-type (8.3.5), that specifies the declared return type of the function. If the declared return type of the function contains a placeholder type, the return type of the function is deduced from return statements in the body of the function, if any.
The sole interpretation of the above would suggest that Clang has a bug.
However, as core issue 1852 specifies the above contradict with § 8.3.5/2 Functions [dcl.fct] and should be altered. The status of the issue is ready which suggests that the the changes have been accepted.
As such, the GCC has a bug that should be reported.
来源:https://stackoverflow.com/questions/24259947/does-a-placeholder-in-a-trailing-return-type-override-an-initial-placeholder