Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does decltype(auto) return a reference here?

I think (thought) I understand auto. Same about decltype. However, in C++14, one can have some thing like decltype(auto) as the return type of a function. Consider the following:

decltype(auto) foo()
{
    int m = 1;
    return m;
}

The return type is int, everything makes sense.

However,

decltype(auto) foo()
{
    int m = 1;
    return (m);
}

returns int& (i.e. reference to int).

I have absolutely NO IDEA why this happens, why do these parentheses make any difference at all!? Hope someone can shed some light on this.

PS: I've also tagged with c++ as there are many more people that check the c++ tag than c++14.

like image 362
vsoftco Avatar asked Dec 18 '14 23:12

vsoftco


People also ask

What does decltype auto do?

decltype(auto) is primarily useful for deducing the return type of forwarding functions and similar wrappers, where you want the type to exactly “track” some expression you're invoking.

What is the difference between auto and decltype Auto?

auto is a keyword in C++11 and later that is used for automatic type deduction. The decltype type specifier yields the type of a specified expression. Unlike auto that deduces types based on values being assigned to the variable, decltype deduces the type from an expression passed to it.


1 Answers

7.1.6.2 [dcl.type.simple]

  1. For an expression e, the type denoted by decltype(e) is defined as follows:
    — if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
    — otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;
    — otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
    — otherwise, decltype(e) is the type of e.

In your example you have return (m) so e is (m). That is not an unparenthesized id-expression or class member access, so we go to the second bullet. It is not an xvalue so we go to the third bullet. It is an lvalue, so the type is T& where T is int.

like image 171
Jonathan Wakely Avatar answered Oct 17 '22 10:10

Jonathan Wakely