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

C++ std::map::iterator是返回值的副本还是返回值本身?,c++,iterator,stdmap,C++,Iterator,Stdmap,我正在尝试在地图中创建地图: typedef map<float,mytype> inner_map; typedef map<float,inner_map> outer_map; 那么真相在哪里呢?这是否是副本?在这种特定情况下,stl\u pair.h中的注释具有误导性 不会有副本,因为映射::迭代器实际上引用了映射内的原始数据(值类型,它本身是一对的),所以它不是副本。因此,iterator::second也指原始数据。value\u type映射是一对,因此它

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

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

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

在这种特定情况下,
stl\u pair.h
中的注释具有误导性


不会有副本,因为
映射::迭代器
实际上引用了映射内的原始数据(
值类型
,它本身是一对
),所以它不是副本。因此,
iterator::second
也指原始数据。
value\u type
映射是一对,因此它有第一个和第二个成员。与所有迭代器一样,映射迭代器是一个伪指针,即它指向集合中的数据,而不是该数据的副本

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

即使您有一个const_迭代器并且下面的类型是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
mapm;
m、 插入件(1,2);
map::const_迭代器citer=m.begin();
迭代器iter=m.begin();
iter->second=3;

std::cout second迭代器,当取消引用时,。

我想为使用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;
}
std::map m({{“a”,“b”},{“c”,“d”});
用于(自动i:m)
{

std::cout+1。将元素设为唯一的\u ptr将清楚地证明这一点,因为您将无法编译以访问已删除的函数(复制ctor)。这是真的,可以通过返回类似myMap.find(myKey)的内容来验证它->其次是引用。因此stl_pair.h中的文档不仅有误导性,而且是错误的。@xamid-Well它没有错,因为
stl_pair.h
文档根本没有引用
std::map
,它的行为方式是因为
std::map::find
返回对存储的
std::pair
的引用因此,该对的
第二个
成员仍然是一个值(而不是一个引用),引用的是该对本身。“第二个元素的副本”文档中提到的事实是,
std::pair::second
持有构造函数中传递的任何值的副本。请看。引用:
引用是对象。它不是指向对象的指针,也不是对象的副本。它是对象。
引用不是副本。我理解的元素是引用的要在映射中“生存”,它不是传递给将其添加到映射中的函数的函数(如果使用了emplace,则该函数也可能不存在)。@xamid我知道引用是什么,但您将映射返回的(=引用)与其第二个成员变量(=值,而不是引用)混淆了对本身。这是用户传递到映射中的值的副本。因此映射本身在pair结构中保存了一个副本。@xamid我完全理解你,你错了:该对不保存引用,因为
second
没有引用类型。确实,映射可能保存了以前不存在的值,但f第一个问题/答案早于移动语义,第二个问题/答案并不改变我们在这里讨论的注释根本不适用于
map
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
std::map<std::string, std::string> m({{"a","b"},{"c","d"}});
for (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<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;
}