In the code below, what are the types of a and b?
template <class T = const int&>
struct A
{
T& a;
T b;
};
int main() {
int i = 1;
A<> a{i, i};
return 1;
}
I used the code from this post that can give the type of a variable. -> post
But, it says both types are i const&
.
int main() {
int i = 1;
A<> a{i, i};
std::cout << type_name<decltype(a.a)>() << std::endl;
std::cout << type_name<decltype(a.b)>() << std::endl;
return 0;
}
Are T&
and T
be the same type in the above case?
Do those ampersands combine and become r-value or some other rule?
T
is const int&
because that's what you told it to be.
T&
is also const int&
because reference collapsing transforms your T&
into T
:
[dcl.ref]/6:
If a typedef-name ([dcl.typedef], [temp.param]) or a decltype-specifier ([dcl.type.simple]) denotes a typeTR
that is a reference to a typeT
, an attempt to create the type “lvalue reference to cvTR
” creates the type “lvalue reference toT
”, while an attempt to create the type “rvalue reference to cvTR
” creates the typeTR
. [ Note: This rule is known as reference collapsing. — end note ] [ Example:int i; typedef int& LRI; typedef int&& RRI; LRI& r1 = i; // r1 has the type int& const LRI& r2 = i; // r2 has the type int& const LRI&& r3 = i; // r3 has the type int& RRI& r4 = i; // r4 has the type int& RRI&& r5 = 5; // r5 has the type int&& decltype(r2)& r6 = i; // r6 has the type int& decltype(r2)&& r7 = i; // r7 has the type int&
— end example ]
This is for convenience, because there is no such thing as const int& &
(reference to reference; not to be confused with rvalue reference type const int&&
which does exist!) and it's handy to be able to just write code like yours without having to manually "get rid of" the "extra" &
.
The rationale behind this rule is explained in more detail here: