C++ std::map::iterator 是否返回值的副本或值本身?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5377434/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:02:05  来源:igfitidea点击:

Does std::map::iterator return a copy of value or a value itself?

c++iteratorstdmap

提问by Morse

I'm trying to create a map inside a map:

我正在尝试在地图内创建地图:

typedef map<float,mytype> inner_map;
typedef map<float,inner_map> outer_map;

Will I be able to put something inside inner map, or does iterator::second returns a copy?

我可以在内部映射中放入一些东西,还是 iterator::second 返回一个副本?

stl_pair.hsuggests the latter:

stl_pair.h建议使用后者:

74: _T2 second;          ///< @c second is a copy of the second object

but my test program run fine with the code like this:

但我的测试程序运行良好,代码如下:

it = my_map.lower_bound(3.1415);
(*it).second.insert(inner_map::value_type(2.71828,"Hello world!");

So where is the truth? Is this a copy or not?

那么真相在哪里呢?这是副本还是不是?

采纳答案by Konrad Rudolph

The comment in stl_pair.his misleading in this specific case.

stl_pair.h在这种特定情况下,中的评论具有误导性。

There will be nocopy, since the map::iteratoractually refers to the original datainside the map (the value_type, which itself is a pair), it's not a copy. Thus iterator::secondalso refers to the original data.

将有没有复制,因为map::iterator实际上指的是原始数据的映射(内部value_type,这本身就是一种pair),它不是一个副本。因此iterator::second也指原始数据。

回答by Matt Gallagher

I want to add a follow up answer to this question for people using C++11 iterators...

我想为使用 C++11 迭代器的人添加这个问题的后续答案......

The following code:

以下代码:

std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (auto i : m)
{
    std::cout << i.first << ": " << i.second << std::endl;
}

doescopy the key and value since "auto" is a value by default, not a const reference (at least that's how it behaves clang 3.1).

确实复制了键和值,因为默认情况下“auto”是一个值,而不是一个常量引用(至少它在 clang 3.1 中是这样的)。

Additionally, the code:

此外,代码:

std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (const std::pair<std::string,std:string>& i : m)
{
    std::cout << i.first << ": " << i.second << std::endl;
}

alsocopies the key and value since the correct code should be:

复制键和值,因为正确的代码应该是:

std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (const auto& i : m)
{
    std::cout << i.first << ": " << i.second << std::endl;
}

or

或者

std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (const std::pair<const std::string,std:string>& i : m)
{
    std::cout << i.first << ": " << i.second << std::endl;
}

回答by CashCow

The value_typea map is a pair and therefore it has members first and second. As with all iterators, a map iterator is a pseudo-pointer, i.e. it points to data within a collection and not copies of that data.

value_type地图是一对,因此它的第一和第二有成员。与所有迭代器一样,映射迭代器是一个伪指针,即它指向集合中的数据而不是该数据的副本。

It is almost certain internally to contain pointers rather than references due to the fact that iterators can be re-assigned (that is what you use them for) and you cannot reassign references to refer to other objects.

由于迭代器可以重新分配(这就是您使用它们的目的)并且您不能重新分配引用以引用其他对象,因此在内部几乎可以肯定包含指针而不是引用。

Even if you have a const_iterator and the type underneath is POD, it must have a pointer to it, in case someone does this:

即使你有一个 const_iterator 并且下面的类型是 POD,它也必须有一个指向它的指针,以防有人这样做:

map< int, int > m;
m.insert( make_pair( 1, 2 );
map<int,int>::const_iterator citer = m.begin();
map<int,int>::iterator iter = m.begin();
iter->second = 3;
std::cout << citer->second << '\n'; // should always print 3

The behaviour should be defined and should output 3, which would not happen if the const_iterator decided to "optimise" after all it's const and only int...

应该定义行为并且应该输出 3,如果 const_iterator 决定“优化”,毕竟它是 const 并且只有 int ,则不会发生这种情况......

回答by Lightness Races in Orbit

Iterators, when dereferenced, give you a reference.

迭代器,当取消引用时,给你一个引用