C++ 映射运算符[](和“at”方法)的返回值

C++ 映射运算符[](和“at”方法)的返回值,c++,c++11,map,stl,C++,C++11,Map,Stl,我有下面的示例代码来解释我的问题。根据STD map container doc(),操作符[](或“at”方法)返回对映射值的引用。我明白了为什么第13行可以正确编译和工作(当我在vec1中插入一个元素时,map中的映射值会得到更新)。我不明白为什么第13行不会导致编译错误,因为vec1不是引用,运算符[]返回引用 1 #include <map> 2 #include <vector> 3 4 using namespace std; 5 6

我有下面的示例代码来解释我的问题。根据STD map container doc(),操作符[](或“at”方法)返回对映射值的引用。我明白了为什么第13行可以正确编译和工作(当我在vec1中插入一个元素时,map中的映射值会得到更新)。我不明白为什么第13行不会导致编译错误,因为vec1不是引用,运算符[]返回引用

  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 }

有人能帮我理解这一点吗?

类型通常可以从引用中复制构造。因此
vec2
只是
端口[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.

关于这两种返回类型的假设,您不能通过返回值来重载函数。

第12行初始化
vec1
,作为对
端口[1]
的引用(或者更准确地说,
端口[1]
引用的
向量
对象)。因此,对
vec1
的任何更改也会更改
端口[1]


第13行将
vec2
初始化为
端口[1]
的副本。因此,对
vec2
的任何更改都不会影响
端口[1]

不确定我是否正确理解了您的问题,因此,我将尝试在12行和13行中向您解释发生了什么

vector<int> &vec1 = port[1];
在这里,您将创建一个新的向量,并将所有数据从
端口[1]
复制到它。它们包含相同的数据,但不指向相同的内存位置

因此,如果您要这样做:

vec1.push_back(1);
vec2.push_back(2);

您将看到,
端口[1]
现在包含一个新的附加元素-
1

,但是
vec1
是一个引用。对不起,我指的是第13行,其中vec2不是引用。(我更正了我原来的问题)谢谢。您的解释和对“c++复制可构造”的进一步阅读澄清了发生了什么以及原因。()我无意中遇到了这个问题,因为我在声明vec类型(如第13行所示)时忘记了输入&when,所以我花了一些时间来解决这个问题。这似乎是一个容易犯的错误,后果严重。有没有办法打开一些编译器选项来警告这种情况。@AhmedA我怀疑任何编译器都不会发出警告,因为这是完全合法的。通常不会将引用绑定到返回值。典型的用例是执行类似于
post[1]的操作。向后推(42)
等。
vector<int> vec2 = port[1];
vec1.push_back(1);
vec2.push_back(2);