In short, I believe both will be deduced to simply return type C.
More explanation below...
This is probably very basic stuff... |
Not at all! You are asking the right questions. I imagine there's only a small percentage of the C++ community that
really understands C++14/17 features in-depth (luckily, people like Cubbi, JLBorges and others visit this site :)). I don't really even understand the nuances of auto/decltype myself... so someone else might want to confirm what I say.
First, this doesn't answer your question from a language-lawyer perspective, but in your particular case, here's a trick you can do:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
struct C
{
int val;
};
decltype(auto) retLocal()
{
C c{4};
return c;
}
C& retLocalBad()
{
C c{4};
return c;
}
int main()
{
C& c1 = retLocal(); // Compiler error!
// error: cannot bind non-const lvalue reference of type ‘C&’ to an rvalue of type ‘C’
C& c2 = retLocalBad(); // Compiler *warning*
// warning: reference to local variable ‘c’ returned [-Wreturn-local-addr]
}
|
Because
C& c1 = retLocal();
simply does not compile, it means that the return type of retLocal
cannot be C&.
_________________________________________________
Another observation, which doesn't completely answer your question, but sheds a clue:
Take a look at the example @
https://en.cppreference.com/w/cpp/language/auto
1 2 3
|
auto c0 = a; // type of c0 is int, holding a copy of a
decltype(auto) c1 = a; // type of c1 is int, holding a copy of a
decltype(auto) c2 = (a); // type of c2 is int&, an alias of a
|
c1 is just an int, which is equivalent to your "return c;" line. It just becomes C.
_________________________________________________
Finally:
In retTemp, C{4} is
a temporary and a prvalue, like you said.
According to
https://en.cppreference.com/w/cpp/language/decltype
C{4} is not an unparenthesized id-expression or an unparenthesized class member access expression, so it must be (2c), which says if the value category of expression is prvalue, then decltype yields T.
In retLocal, c is an unparenthesized id-expression (to my understanding), so "decltype yields the type of the entity named by this expression", where the entity here is the C object.