【问题标题】:Why can I use a reference to non-const with 'auto' but not with 'std::pair' in range-based for-loop through 'std::unordered_map'?为什么我可以通过'std::unordered_map'在基于范围的for循环中使用'auto'而不是'std::pair'对非常量的引用?
【发布时间】:2018-03-19 17:46:08
【问题描述】:

使用 C++14(也应该影响 C++11)我对 auto 在通过 std::unordered_map 的基于范围的 for 循环中感到困惑,而不是使用像 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 循环使用迭代器。但是为什么我可以使用auto(循环1)引用非常量的std::unordered_map,但在使用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

【问题讨论】:

  • A std::unordered_map&lt;int,int&gt; 不包含 std::pair&lt;int,int&gt; 的实例。它拥有std::pair&lt;const int, int&gt;。所以你所有的pair&lt;int,int&gt; 都是临时副本。我认为这回答了您的所有 5 个问题。
  • 在此处查看 value_typeen.cppreference.com/w/cpp/container/unordered_map 请注意,在您的情况下,它将是 std::pair&lt;const int, int&gt;
  • 哇,感谢您提供快速而有用的答案!这是我在这里的第一个问题,我很高兴有你们。 :-)
  • std::map&lt;K, V&gt;::value_type 的类型是什么?不是std::pair&lt;K, V&gt;
  • @MartinYork 不,它是std::pair&lt;const K, V&gt;(注意const),您可以查看here 并验证here

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


【解决方案1】:

std::unordered_map 的值类型是std::pair&lt;const Key, T&gt;。见the documentation at cppreference.com

因此,您不能使用 std::pair&lt;int, int&gt;&amp; 作为类型来迭代此类对象的内容。


这就解释了原因

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

不起作用。


以下作品

for(auto const & pair : map)

因为类型是由编译器为你推断出来的。


以下作品

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

因为pair 绑定到由std::pair&lt;const int, int&gt; 构造的std::pair&lt;int, int&gt; 类型的临时对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 2015-01-15
    • 2021-10-21
    • 1970-01-01
    相关资源
    最近更新 更多