Reputation: 21307
I am rather confused with structural binding. Even if I use const
and by-value (without &
) structural binding as in this example:
#include <iostream>
#include <tuple>
int main()
{
int x = 0;
std::tuple<int&> p(x);
const auto [a] = p;
a++;
std::cout << x << '\n';
}
It still modifies x
and prints 1
: https://gcc.godbolt.org/z/jc8hxE8M6
Could you please explain why it works that way and want changes if I add &
before [a]
or remove const
?
Upvotes: 5
Views: 97
Reputation: 311088
The compiler deduces the type similar to the following
typedef int & Ref;
It is the element type of the std::tuple
object.
If you will then write for example
int x = 0;
const Ref rx = x;
then the last declaration is equivalent to
int & const rx = x;
But opposite to pointers references may not be constant in this sense. So the qualifier const is just ignored and you have
int & rx = x;
Here is a demonstrative program.
#include <tuple>
#include <type_traits>
int main()
{
int x = 0;
std::tuple<int &> p( x );
const auto [a] = p;
std::cout << std::is_same_v<decltype( a ), int &> << '\n';
std::tuple<int *> p1( &x );
const auto [b] = p1;
std::cout << std::is_same_v<decltype( b ), int * const> << '\n';
}
The program output is
1
1
Upvotes: 1
Reputation: 123104
See the example on cppreference:
The portion of the declaration preceding
[
applies to the hidden variable e, not to the introduced identifiers.int a = 1, b = 2; const auto& [x, y] = std::tie(a, b); // x and y are of type int& auto [z, w] = std::tie(a, b); // z and w are still of type int& assert(&z == &a); // passes
Where e
refers to
A structured binding declaration first introduces a uniquely-named variable (here denoted by e) to hold the value of the initializer, as follows: [...]
The const
in your example does not apply to a
, why it can still be useful is demonstrated by the next example:
int a = 1; const auto& [x] = std::make_tuple(a); // OK, not dangling auto& [y] = std::make_tuple(a); // error, cannot bind auto& to rvalue std::tuple auto&& [z] = std::make_tuple(a); // also OK
Upvotes: 6