Richard
Richard

Reputation: 8758

Deducing the const (return) type with decltype and auto

Why does decltype deduce const from a variable but not from a function?

const int f()
{
    const int i = 1;
    return i;
}
decltype(auto) i_fromFunc = f(); // i_fromFunc is of type 'int'

const int i = 1;
decltype(auto) i_fromVar = i; // i_fromVar is of type 'const int'

Example with more deduction variants (see at compiler explorer).

const int func()
{
    const int i = 1;
    return i;
}

decltype(auto) funcDecltype()
{
    const int i = 1;
    return i;        
}

auto funcAuto()
{
    const int i = 1;
    return i;
}

void DeduceFromFunc()
{
    decltype(auto) i = func(); // i is of type 'int', similar to auto i = func()
    i = 2;
    decltype(auto) iDT = funcDecltype(); // iDT is of type 'int', similar to auto iDT = funcDecltype()
    iDT = 2;
    decltype(auto) iA = funcAuto(); // iA is of type 'int', similar to auto iA = funcAuto().
    iA = 2;

    // For the sake of completeness:

    const auto ci = func(); // const int
    //ci = 2; // Not mutable.

    //auto& iRef = func(); // non const lvalue of 'int&' can't bind to rvalue of 'int'
    const auto& ciRef = func(); // const int &
    //ciRef = 2; // Not mutable.

    auto&& iRV = func(); // int &&
    iRV = 2;
    const auto&& ciRV = func(); // const int &&
    //ciRV = 2; // Not mutable.
}

const int gi = 1;

void DeduceFromVar()
{
    auto i_fromVar = gi; // i_fromVar is of type 'int'.
    i_fromVar = 2;
    decltype(auto) iDT_fromVar = gi; // iDT_fromVar is of type 'const int'
    //iDT = 2; // Not mutable.

    // For the sake of completeness:
    auto& iRef = gi; // reference to const int
    //iRef = 2; // Not mutable.
    auto&& iRVRef = gi; // rvalue ref to const int
    //iRVRef = 2; // Not mutable.
}

int main()
{
    DeduceFromFunc();
    DeduceFromVar();
}

Why the constness of iDT_fromVar differs from i_fromVar? (decltype(auto) vs auto for vars)

Why the constness of iDT_fromVar differs from iDT? (question from above)

Why i_fromVar and i/iDT/iA have the same constness when iDT_fromVar and iDT have not?

Upvotes: 0

Views: 126

Answers (1)

M.M
M.M

Reputation: 141628

There are no const prvalues of non-class type. The function const int f() is basically equivalent to int f().

The relevant clause in C++17 is [expr]/6:

If a prvalue initially has the type “cv T ”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.

You would see different behaviour if trying similar code with a class type instead of int as the return type.

Upvotes: 3

Related Questions