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

时间:2018-03-19 17:46:09

标签: c++ c++11 for-loop stl auto

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

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

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

  • 问题4(继续0和1):我知道基于范围的for循环使用迭代器。但是为什么我可以使用std::unordered_map(循环1)参考非const来迭代auto,但是在使用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;
}

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

1 个答案:

答案 0 :(得分:6)

std::unordered_map的值类型为std::pair<const Key, T>。请参阅the documentation at cppreference.com

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

这解释了为什么

for(std::pair<int, int> & pair : map) { ... }

不起作用。

以下作品

for(auto const & pair : map)

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

以下作品

for(std::pair<int, int> const & pair : map)

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