Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are structured bindings in range-based for-loop just a copy and not a reference?

I have the following code:

#include "stdafx.h"
#include <unordered_map>
#include <cassert>
int main()
{
    struct Foo { int a; };
    std::unordered_map<int, Foo> foos{ { 0, { 3 } }, { 1, { 4 } } };
    for (auto &[i, foo] : foos)
    {
        foo.a = 6; //doesn't change foos[i].a
        assert(&foo.a == &foos[i].a); //does not pass
    }

    auto &[i, foo] = *foos.begin();
    foo.a = 7; //changes foo[0].a
    assert(&foo.a == &foos[0].a); //passes
}

My question:

Why doesn't the first assert statement pass while the second passes? Why can't I change the value of a foo in the foos map in a range-based for-loop?

Compiler: MSVS++17 Visual studio 15.3.2

Edit: The code now compiles if copy pasted into a visual studio project.

like image 740
Jupiter Avatar asked Aug 27 '17 18:08

Jupiter


People also ask

What are structured bindings?

Like a reference, a structured binding is an alias to an existing object. Unlike a reference, a structured binding does not have to be of a reference type. attr(optional) cv-auto ref-qualifier(optional) [ identifier-list ] = expression ; (1)

What are range-based for loops?

Range-based for loop (since C++11) Executes a for loop over a range. Used as a more readable equivalent to the traditional for loop operating over a range of values, such as all elements in a container.

What is a range loop?

To loop through a set of code a specified number of times, we can use the range() function, The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and ends at a specified number.


1 Answers

I posted a bugreport in VS and it is under investigation now.

like image 199
Jupiter Avatar answered Sep 18 '22 15:09

Jupiter