colon in for loop in C++

岁酱吖の 提交于 2021-02-20 01:01:23

问题


In the following code I am trying to edit the contents of an unordered_map:

class A {
public:
    A() {std::cout << "Constructor called, address=" << this << std::endl;val=1;}
    int val;
};

void main(void) {
    std::unordered_map<int,A> um;

    for (int i=0;i<3;i++)
        std::cout << "um[" << i << "]=" << &(um[i]) << ", val=" << um[i].val << std::endl;
    for (auto it : um)
        std::cout << "&it.second=" << &(it.second) << ", val=" << it.second.val << std::endl;

    int index = 1;      
    for (auto um_it : um)
        um_it.second.val = index++;

    for (int i=0;i<3;i++)
        std::cout << "um[" << i << "]=" << &(um[i]) << ", val=" << um[i].val << std::endl;
    for (auto it : um)
        std::cout << "&it.second=" << &(it.second) << ", val=" << it.second.val << std::endl;
}

The output of the above is:

Constructor called, address=0x8dcb2c 
um[0]=0x8dcb2c, val=1 
Constructor called, address=0x8dc7ac 
um[1]=0x8dc7ac, val=1 
Constructor called, address=0x8dc42c 
um[2]=0x8dc42c, val=1 
&it.second=0x7ffc62f24484, val=1 
&it.second=0x7ffc62f24484, val=1 
&it.second=0x7ffc62f24484, val=1 
um[0]=0x8dcb2c, val=1 
um[1]=0x8dc7ac, val=1 
um[2]=0x8dc42c, val=1 
&it.second=0x7ffc62f24484, val=1 
&it.second=0x7ffc62f24484, val=1 
&it.second=0x7ffc62f24484, val=1

When I replace the editing code with:

int index = 1;      
for (auto um_it = um.begin(); um_it != um.end(); ++um_it)
    um_it->second.val = index++;

The output is:

Constructor called, address=0x9d8b2c
um[0]=0x9d8b2c, val=1
Constructor called, address=0x9d87ac
um[1]=0x9d87ac, val=1
Constructor called, address=0x9d842c
um[2]=0x9d842c, val=1
&it.second=0x7fffd2201c34, val=1
&it.second=0x7fffd2201c34, val=1
&it.second=0x7fffd2201c34, val=1
um[0]=0x9d8b2c, val=3
um[1]=0x9d87ac, val=2
um[2]=0x9d842c, val=1
&it.second=0x7fffd2201c34, val=1
&it.second=0x7fffd2201c34, val=2
&it.second=0x7fffd2201c34, val=3

I understand from the results that in the first version the code affects a copy of the objects, but it seems strange. I also expected the copy constructor to be called but it was not. I'd be happy if someone can explain what is going on behind the scenes and what would be the best way to iterate through an unordered_map without making redundant copies.


回答1:


In the line:

for (auto um_it : um)

um_it is not an iterator. It is a copy of a value in the map. You then modify that copy in the loop body, leaving the map unchanged. This would call the copy-constructor of A for each iteration.

Instead you can operate by reference:

for ( auto& um_item : um )

when um_item refers to an entry in the map. (When using range-based for loop, you cannot access the underlying iterator, you can only access each element or a copy of it).



来源:https://stackoverflow.com/questions/36296668/colon-in-for-loop-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!