在C ++中的for循环中冒号 [英] colon in for loop in C++

查看:347
本文介绍了在C ++中的for循环中冒号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下代码中,我试图编辑unordered_map的内容:

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;
}

上面的输出是:

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++;

输出为:

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

我从结果中了解到,在第一个版本中,代码会影响对象的副本,但这似乎很奇怪.我也希望复制构造函数被调用,但事实并非如此.如果有人可以解释幕后发生的事情以及什么是遍历unordered_map而不制作多余副本的最佳方法,我将很高兴.

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.

推荐答案

在此行:

for (auto um_it : um)

um_it 不是迭代器.它是映射中值的副本.然后,您可以在循环主体中修改该副本,从而使映射保持不变.对于每次迭代,这将调用 A 的复制构造函数.

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 )

um_item 引用地图中的一个条目时.(当使用基于范围的for循环时,您不能访问基础的迭代器,只能访问每个元素或其副本.)

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).

这篇关于在C ++中的for循环中冒号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆