Reputation: 157374
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?
Upvotes: 6
Views: 434
Reputation: 131799
auto
is required when introducing a trailing-return-type.
§8.3.5 [dcl.fct] /2
In a declaration
T D
whereD
has the form
D1 (
parameter-declaration-clause
)cv-qualifier-seq
optref-qualifier
optexception-specification
optattribute-specifier-seq
opttrailing-return-type
and the type of the contained declarator-id in the declaration
T D1
is “derived-declarator-type-listT
”,
T
shall be the single type-specifier auto. [...]
See also Core Issue 1852 for the apparent contradiction with [dcl.spec.auto]/1.
Upvotes: 14
Reputation: 42909
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]:
1
Theauto
anddecltype(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.
2
The 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.
Upvotes: 3