Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does auto seemingly deduce a reference when using structured bindings?

Consider the following code that uses structured bindings from C++17:

int a = 0, b = 0;
auto [x, y] = std::tie(a, b);
y = 1;
std::cout << a << ' ' << b << '\n';

Since I used auto, I would expect the code to print 0 0 as y should be a copy. However, it prints 0 1. Why? I thought that a bare auto never deduces a reference.

like image 744
s3rvac Avatar asked Dec 08 '17 16:12

s3rvac


People also ask

Does auto deduce reference?

One of the first things that C++ programmers learn about auto is that bare auto never deduces a reference. In the present post, I show you two examples when it seemingly does. The first one involves proxy objects. The second one concerns structured bindings from C++17.

How do structured bindings work?

A structured binding declaration introduces all identifiers in the identifier-list as names in the surrounding scope and binds them to subobjects or elements of the object denoted by expression. The bindings so introduced are called structured bindings.

Will auto be a reference C++?

The auto there works just the same. for(auto val : range) will always copy, for(auto& ref : range) will always be a reference.

What is Auto& C++?

The auto keyword in C++ automatically detects and assigns a data type to the variable with which it is used. The compiler analyses the variable's data type by looking at its initialization. It is necessary to initialize the variable when declaring it using the auto keyword.


Video Answer


1 Answers

As cppreference notes, the portion of the declaration preceding [ (i.e. auto in your case) does not apply to the introduced identifiers. Instead, it applies to a hidden variable that is created by the compiler under the covers. Your structured-binding declaration

auto [x, y] = std::tie(a, b);

is roughly equivalent to

auto e = std::tie(a, b);
decltype(std::get<0>(e)) x = std::get<0>(e);
decltype(std::get<1>(e)) y = std::get<1>(e);

As you can see, auto is applied to the hidden variable e and not to the declaration of x and y. The type of e is std::tuple<int&, int&>, and decltype(std::get<1>(e)) gives you int&.

like image 96
s3rvac Avatar answered Nov 11 '22 00:11

s3rvac