为什么我可以在基于范围的for-loop到'std :: unordered_map'中使用带有'auto'但不带'std :: pair'的非const引用?

sal*_*uto 0 c++ for-loop stl auto c++11

使用C++ 14(也应该影响C++ 11)我auto在基于范围的for循环中感到困惑std::unordered_map,与使用std::pair<int, int>下面代码中的确切类型相反.

更具体地说,我有一些关于这个例子的(相关)问题:

  • 问题0 :(循环0)为什么std::pair<int, int> &不允许但是auto &在循环1中?
  • 问题1 :(循环1)为什么/如何/何时auto与确切类型不同(如std::pair<int, int>循环0)?
  • 问题2 :(循环2)为什么这个不同的指针比循环3中的不同?
  • 问题3 :(循环3)为什么这是所有映射条目的相同指针?

  • 问题4(继续0和1):我知道基于范围的for循环使用迭代器.但是为什么我可以std::unordered_map使用auto(循环1)迭代引用非const ,但是在使用std::pair(循环0)时不能?


#include<iostream>
#include <unordered_map>
#include <utility>

int main()
{
    std::unordered_map<int, int> map;
    map[3] = 333;
    map[2] = 222;
    map[1] = 111;

    // loop 0
    // QUESTION 0: Why is `std::pair<int, int> &` not allowed but `auto &` in loop 1 is?
    // for(std::pair<int, int> & pair : map)
    //     pair.second++;

    // loop 1
    for(auto & pair : map)
        // QUESTION 1: Why/How/When does `auto` differ from the exact type (like `std::pair<int, int>` in loop 0)?
        pair.second++;

    // loop 2
    for(auto const & pair : map)
        // QUESTION 2: Why are this different pointers than in loop 3?
        std::cout << pair.first << " (" << &pair.first << ") : " << pair.second << " (" << &pair.second << ")" << std::endl;

    // loop 3
    for(std::pair<int, int> const & pair : map)
        // QUESTION 3: Why are this the same pointers for all map entries?
        std::cout << pair.first << " (" << &pair.first << ") : " << pair.second << " (" << &pair.second << ")" << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

您可以在此处运行代码:https://www.onlinegdb.com/rkBkKDatf

R S*_*ahu 6

a的值类型std::unordered_mapstd::pair<const Key, T>.请参阅cppreference.com上的文档.

因此,您不能使用std::pair<int, int>&类型来迭代此类对象的内容.


这解释了原因

for(std::pair<int, int> & pair : map) { ... }
Run Code Online (Sandbox Code Playgroud)

不起作用.


以下作品

for(auto const & pair : map)
Run Code Online (Sandbox Code Playgroud)

因为编译器会为您推断出类型.


以下作品

for(std::pair<int, int> const & pair : map)
Run Code Online (Sandbox Code Playgroud)

因为pair绑定到一个std::pair<int, int>由a构造的类型的临时对象std::pair<const int, int>.