I'm looking at the isocpp.org FAQ on C++14 language extensions, reading about decltype(auto)
:
...
Note:
decltype(auto)
is primarily useful for deducing the return type of forwarding functions and similar wrappers, as shown above, where you want the type to exactly “track” some expression you’re invoking. However, decltype(auto) is not intended to be a widely used feature beyond that. In particular, although it can be used to declare local variables, doing that is probably just an antipattern since a local variable’s reference-ness should not depend on the initialization expression. Also, it is sensitive to how you write the return statement. These two functions have different return types:decltype(auto) look_up_a_string_1() { auto str = lookup1(); return str; } decltype(auto) look_up_a_string_2() { auto str = lookup1(); return(str); }
The first returns string, the second returns
string &
, which is a reference to the local variablestr
.
My question: Shouldn't the return types in the example be the other way around, I mean, the parentheses should form an expression whose type should be either a non-reference (or an rvalue-reference?); and without the parentheses, saying str
means "lvalue reference to str
". Am I wrong?
The FAQ is correct, intuition notwithstanding
(@lubgr pointed out a relevant answer to another question)
The language specification says:
So, the non-parenthesized case is an exceptional/special case, apparently introduced to facilitate returning references with decltype(auto); without the special-casing, the rule @StoryTeller quotes is in effect:
and this would have make it difficult to return references.
Definitely ranks up there with other magick definitions such as the destruction order of tuples or empty strings having 0 at index 0, temporary lifetime extension with references and other similar wonders...