Reputation: 219
I would like to ask a question about structural binding and how the variables get their types. Here is the code I compile.
struct T {
explicit T(int a = 1) {
a_ = a;
std::cout << "Default" << std::endl;
}
T(const T& t) {
a_ = t.a_;
std::cout << "Copy" << std::endl;
}
int a_;
};
int main() {
std::tuple<bool, T> bi{true, T(1)};
std::cout << "START" << std::endl;
auto& [b, i] = bi;
static_assert(std::is_same<decltype(i), T>::value);
std::cout << i.a_ << std::endl;
i.a_++;
std::cout << i.a_ << std::endl;
std::cout << (&i == &get<1>(bi)) << std::endl;
return 0;
}
The code compiles and the result is:
Default
Copy
START
1
2
1
As you can see the variable i
actually refers to get<1>(bi)
.
However, the type of the variable i
is T
since std::is_same<decltype(i), T>::value
.
Could you please explain why structural binding works this way?
I have read about it in the book "C++ Templates: The Complete Guide"
and the authors state that the variable i
must have type std::tuple_element<1, std::tuple<bool, T> >::type&&
. I don't understand why decltype(i)
is just T
.
Upvotes: 1
Views: 318
Reputation: 170104
decltype
is funny that way. Its specification contains a special clause for structured bindings
4 For an expression
e
, the type denoted bydecltype(e)
is defined as follows:
if
e
is an unparenthesized id-expression naming a structured binding ([dcl.struct.bind]),decltype(e)
is the referenced type as given in the specification of the structured binding declaration;...
So while each structured binding is indeed a reference into the tuple, decltype
reports the type of the referent. Likely since structured bindings are meant to feel like regular named variables.
Upvotes: 3