Reputation: 8758
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
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
”, whereT
is a cv-unqualified non-class, non-array type, the type of the expression is adjusted toT
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