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
Does std::map::iterator return a copy of value or a value itself?
提问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.h
is misleading in this specific case.
stl_pair.h
在这种特定情况下,中的评论具有误导性。
There will be nocopy, since the map::iterator
actually refers to the original datainside the map (the value_type
, which itself is a pair
), it's not a copy. Thus iterator::second
also 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_type
a 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.
迭代器,当取消引用时,给你一个引用。