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

时间:2011-03-21 12:15:33

标签: c++ iterator stdmap

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

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

我能在内部地图中放置一些东西,还是iterator :: second会返回一个副本?

stl_pair.h 建议后者:

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

但我的测试程序运行正常,代码如下:

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

那么事实在哪里?这是副本吗?

4 个答案:

答案 0 :(得分:24)

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

以下代码:

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

复制键和值,因为默认情况下“auto”是一个值,而不是const引用(至少它是clang 3.1的行为方式)。

此外,代码:

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

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

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

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

答案 1 :(得分:23)

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

将会有 no 副本,因为map::iterator实际上是指地图内的原始数据value_type,它本身就是一个pair),它不是副本。因此iterator::second也指原始数据。

答案 2 :(得分:4)

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

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

即使你有一个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

应该定义行为,并且应该输出3,如果const_iterator决定在所有它的const之后“优化”并且只有int ...这将不会发生...

答案 3 :(得分:0)

Iterators,取消引用后,give you a reference