Does the placeholder in the return type of the return starting placeholder replace?

g ++ apparently accepts any combination of auto and decltype(auto) as the start and return 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 should indicate the return type is 'auto', not 'decltype (auto)' ( demo ).

Which compiler is right? Which rule ( auto or decltype(auto) ) should be used in each case? And does it make sense to use a placeholder type in the return type?

+6
source share
2 answers

auto is required when entering a return type.

ยง8.3.5 [dcl.fct] / 2

In the declaration of TD , where D has the form

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

and the type of the declaration identifier contained in the ad T D1 is the "derived-declarator-type-list T ",

T must be the only type specifier. [...]

See also Core Issue 1852 for apparent contradiction with [dcl.spec.auto] / 1.

+14
source

Edit after @Xeo constructive comments:

This problem seems to be caused by a contradiction between the two places of the draft standard.

In accordance with the draft standard ยง 7.1.6.4, the auto-specialist [dcl.spec.auto]:

1 Type decltype(auto) auto and decltype(auto) indicate the type of placeholder , which will be replaced later either by subtraction from the initializer, or by explicit specification using the trailing-return-type function. An autotype specifier is also used to indicate that lambda is a common lambda.

2 A placeholder type may appear with a function declaration in the declaration-specifier-seq, type-specifier-seq, convert-function-id or trailing-return-type , in any context where such a declarator is valid. If the declarator function includes a type trailing-return-type (8.3.5), which sets 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 derived from the return statements in the function body, if any.

A single interpretation of the foregoing suggests that the Clan has a mistake.

However, since the main problem of 1852 indicates that the above is a contradiction with ยง 8.3.5 / 2 Functions [dcl.fct] and must be changed, the status of the problem is ready, which suggests that the changes have been accepted.

Therefore, the GCC has an error that should be reported.

+2
source

Source: https://habr.com/ru/post/970937/


All Articles