为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
Why does const std::pair<K,V>& in range-based for loop on std::map not work?
在基于循环的范围内通过const auto& entry
访问std::map
的元素时,我会得到对映射中实际数据的引用。另一方面,使用const 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::map
的value_type是std::pair<const Key, T>
。但我真的不明白在第二个基于范围的循环的情况下会发生什么。
std::map<K, V>::value_type
是std::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<const std::__cxx11::basic_string<char>, int>
'的表达式初始化类型为'std::pair<std::__cxx11::basic_string<char>, int>&
'的引用无效
如前所述,std::map
内部的类型是std::pair<const Key, T>
,而不是std::pair<Key, T>
。这意味着,当我们迭代映射并提取const std::pair<Key, T>&
s时,我们无法获得对元素的引用,但正在发生其他事情。这是寿命延长此循环:
for(const std::pair<std::string, int>& entry : my_map) {
...
}
大致相当于这个循环:
for(const std::pair<std::string, int> entry : my_map) {
...
}
所以你实际上得到了地图上每个条目的副本。
- 使用std::transform将一个范围的元素添加到另一个范围中
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 在基于范围的 for 循环期间插入 std::list 的后面
- std::map, std::unordered_map - 缩小初始值设定项列表中的转换范围
- 如何读/写或遍历 std::array 中的特定元素范围?
- 从函数返回范围视图时,带有std::span:中间对象所有权的C++Ranges-v3
- 为什么范围算法与 std 的迭代器不兼容?
- C ++枚举范围无法使用-std=c ++ 98进行编译,但使用-std=c ++ 11可以
- std::线程不是全局变量,但在到达创建它的函数的末尾时不会超出范围?
- C++11 基于范围的 for 循环,用于 std::list
- 使用范围库初始化 std::vector
- 示例代码中使用分隔符将 std::string 拆分为 std::vector 的范围问题
- 读取互斥对象范围之外的volatile变量,而不是std::atomic
- 将视图范围设置为std::vector
- std::vector 范围构造函数可以调用显式转换吗?
- 访问基于范围的循环(如for_each)中的std::map迭代器
- std::copy,std::copy_backward和重叠范围
- 使用 std::binomial_distribution 在范围之间生成随机数