我有以下示例代码来解释我的问题。根据STD地图容器doc(http://www.cplusplus.com/reference/map/map/operator%5B%5D/),operator [](或“at”方法)返回对映射值的引用。我明白为什么第13行编译并正常工作(当我将元素插入vec1时,映射中的映射值会更新)。我不明白为什么第13行不会导致编译错误,因为vec1不是引用而operator []返回引用。
1 #include <map>
2 #include <vector>
3
4 using namespace std;
5
6 int main()
7 {
8 map<int, vector<int> > port;
9
10 port[1] = vector<int>(1, 10);
11
12 vector<int> &vec1 = port[1]; // <===
13 vector<int> vec2 = port[1]; // <===
14
15 return 0;
16 }
我想也许operator []的实际实现被重载以返回两种类型(值和引用)。但是,当我查看“map”头文件时,它似乎没有(除非我遗漏了一些东西):
文件:/ usr / include / c ++ / 4.7 / profile / map.h
// 23.3.1.2 element access:
mapped_type&
operator[](const key_type& __k)
{
__profcxx_map_to_unordered_map_find(this, size());
return _Base::operator[](__k);
}
#ifdef __GXX_EXPERIMENTAL_CXX0X__
mapped_type&
operator[](key_type&& __k)
{
__profcxx_map_to_unordered_map_find(this, size());
return _Base::operator[](std::move(__k));
}
#endif
有人可以帮我理解这个吗?
答案 0 :(得分:6)
类型通常可以从引用中复制构造。因此vec2
只是port[1]
返回的引用引用的值的副本。这是一个涉及ints
的简单示例:
int i = 42;
int j& = i; // j is a reference to i
int k = j; // k is a copy of the int that j refers to, i.e. i.
关于两种返回类型的假设,不能通过返回值重载函数。
答案 1 :(得分:2)
第12行初始化vec1
以引用port[1]
(或者更确切地说,vector<int>
引用的port[1]
对象。因此,对vec1
的任何更改也会更改port[1]
。
第13行将vec2
初始化为port[1]
的副本。因此,对vec2
的任何更改都不会影响port[1]
。
答案 2 :(得分:2)
我不确定我是否正确理解了您的问题,所以,我只是试着向您解释12行和13行中发生了什么。
vector<int> &vec1 = port[1];
在这里,您要为向量创建引用,并使用port[1]
对其进行初始化。所以,实际上,他们现在指向相同的内存位置。
vector<int> vec2 = port[1];
在这里,您要创建新向量并将port[1]
中的所有数据复制到其中。它们包含相同的数据,但它们并未指向相同的内存位置。
所以,如果你这样做:
vec1.push_back(1);
vec2.push_back(2);
您会看到,port[1]
现在包含一个新的附加元素 - 1
。