首页 > 解决方案 > 为什么 const std::pair& 在 std::map 上基于范围的 for 循环不起作用?

问题描述

基于范围的 for 循环std::map中访问via的元素时,我得到了对地图中实际数据的引用。另一方面,使用不会引用const auto& entryconst std::pair<K,V>&std::map

考虑这个例子(用 gcc 7.4 编译,-std=c++14)

#include <map>
#include <string>
#include <iostream>

int main(void)
{
    std::map<std::string, int> my_map {{"foo", 42}};
    for(const auto& entry : my_map)
        std::cout << entry.first << ' ' << entry.second << ' ' << &(entry.second) << std::endl;
    for(const std::pair<std::string, int>& entry : my_map)
        std::cout << entry.first << ' ' << entry.second << ' ' << &(entry.second) << std::endl;
    return 0;
}

输出:

foo 42 0x11a7eb0
foo 42 0x7ffec118cfc0

我知道std::mapvalue_type 是std::pair<const Key, T>. 但我真的不明白在第二个基于范围的循环中发生了什么。

标签: c++c++11c++14stdmap

解决方案


std::map<K, V>::value_typestd::pair<const K, V>,不是std::pair<K, V>(见cppreference

#include <map>
#include <string>
#include <iostream>

int main(void)
{
    std::map<std::string, int> my_map {{"foo", 42}};
    for(const auto& entry : my_map)
        std::cout << entry.first << ' ' << entry.second << ' ' << &(entry.second) << std::endl;
    for(const std::pair<std::string, int>& entry : my_map)
        std::cout << entry.first << ' ' << entry.second << ' ' << &(entry.second) << std::endl;
    for(const std::pair<const std::string, int>& entry : my_map)
        std::cout << entry.first << ' ' << entry.second << ' ' << &(entry.second) << std::endl;
    return 0;
}

示例输出

foo 42 0x2065eb0
foo 42 0x7ffc2d536070
foo 42 0x2065eb0

您的第二个循环有效,因为它正在创建一个临时std::pair<std::string, int>并将其绑定到您的参考(说明)。如果您尝试改用非常量引用,您会看到它失败(因为它不能绑定到临时引用):

std::pair<std::__cxx11::basic_string<char>, int>&错误:从类型 ' ' 的表达式中对类型 ' std::pair<const std::__cxx11::basic_string<char>, int>'的引用的无效初始化


推荐阅读