我正在尝试在地图中创建地图:
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!");
那么真相在哪里呢?这是不是副本?
我想为使用 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;
}
stl_pair.h
中的评论在这种具体情况下具有误导性。
不会有副本,因为map::iterator
实际上指的是地图内的原始数据(
value_type
,它本身就是一个
pair
),它不是副本。因此
iterator::second
也指原始数据。
value_type
映射是一对,因此它有第一个和第二个成员。与所有迭代器一样,映射迭代器是一个伪指针,即它指向集合中的数据,而不是该数据的副本。几乎可以肯定,内部包含指针而不是引用,因为迭代器可以重新分配(这就是您使用它们的目的),并且您不能重新分配引用来引用其他对象。
即使你有一个 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,则不会发生这种情况...
给你一个引用。
#include <iostream>
#include <map>
using namespace std;
class object
{
public:
object(int v)
: m_v(v)
{
cout << "object() addr " << hex << this << "\n";
}
object(const object& other)
: m_v(other.m_v)
{
cout << "object(&) addr " << hex << this << "\n";
}
object& operator=(const object& other)
{
cout << "Operator= (this addr " << hex << this << ")\n";
m_v = other.m_v;
return *this;
}
int m_v;
};
std::ostream& operator<<(std::ostream& os, object const& obj)
{
return os << std::to_string(obj.m_v);
}
int main() {
cout << "Constructing:\n";
std::map<int, object> objects({{0, 0},{1,1}});
cout << "Emplace:\n";
objects.emplace(2, 2);
cout << "For loop:\n";
for (const std::pair<const int, object>& i : objects)
{
std::cout << i.first << ": " << i.second << std::endl;
}
cout << "Find:\n";
const auto v = objects.find(2);
if (v != objects.end())
{
std::cout << v->first << ": " << v->second << std::endl;
}
else
{
std::cout << "Not found.\n";
}
// your code goes here
return 0;
}
输出:
Constructing:
object() addr 0x7ffc7e8e7aa4
object() addr 0x7ffc7e8e7aac
object(&) addr 0x5617fb0eaea4
object(&) addr 0x5617fb0eaed4
Emplace:
object() addr 0x5617fb0eaf04
For loop:
0: 0
1: 1
2: 2
Find:
2: 2