我可以使用基于范围的 for 循环轻松迭代地图的值吗?
Posted
技术标签:
【中文标题】我可以使用基于范围的 for 循环轻松迭代地图的值吗?【英文标题】:Can I easily iterate over the values of a map using a range-based for loop? 【发布时间】:2012-10-16 17:24:11 【问题描述】:是否可以仅使用“foreach”来迭代 std::map
中的所有值?
这是我当前的代码:
std::map<float, MyClass*> foo ;
for (map<float, MyClass*>::iterator i = foo.begin() ; i != foo.end() ; i ++ )
MyClass *j = i->second ;
j->bar() ;
有没有办法可以做到以下几点?
for (MyClass* i : /*magic here?*/)
i->bar() ;
【问题讨论】:
为什么你不喜欢 i->second->bar() ? 看看[这个问题的答案][1]。我认为这正是你所需要的。 [1]:***.com/questions/6963894/… @LyubomirVasilev:不,那只是询问如何在一般地图上迭代范围。这个问题询问如何仅对值进行专门迭代。 @Xeo 啊,我明白了。我忽略了这一点。 【参考方案1】:由于C++20,您可以将范围适配器std::views::values
从Ranges library 添加到您的range-based for loop。这样您就可以实现与Xeo's answer 中的解决方案类似的解决方案,但无需使用 Boost:
#include <map>
#include <ranges>
std::map<float, MyClass*> foo;
for (auto const &i : foo | std::views::values)
i->bar();
Code on Wandbox
【讨论】:
【参考方案2】:从 C++1z/17 开始,您可以使用结构化绑定:
#include <iostream>
#include <map>
#include <string>
int main()
std::map<int, std::string> m;
m[1] = "first";
m[2] = "second";
m[3] = "third";
for (const auto & [key, value] : m)
std::cout << value << std::endl;
【讨论】:
结构化绑定很棒,但我编译时使用 -Werror 和未使用的变量,因为密钥没有被大量使用 :) 试试[[maybe_unused]]
属性。见这里***.com/q/41404001/580083
@galois 和 @Daniel,对不起,如果这是一个基本问题,那么 Structured Bindings 到底是什么?提前非常感谢!
@Milan 你试过用谷歌搜索吗?周围有很多解释。
@DanielLangr 我正在阅读一个答案,当我读到一个新单词时,我就在这里发表了评论。但你是对的......我应该先用谷歌搜索它。对于那个很抱歉。 (对于未来的读者:我发现这个关于 Structured Bindings 的简短视频非常有用:youtu.be/eUsTO5BO3WI)【参考方案3】:
std::map<float, MyClass*> foo;
for (const auto& any : foo)
MyClass *j = any.second;
j->bar();
在 c++11(也称为 c++0x)中,您可以像在 C# 和 Java 中一样进行此操作
【讨论】:
“你能做到”是什么意思?您是指一般的基于范围的 for 循环吗? 是的!新的 C++ 标准 c++11 引入了新的 for-range 语法特性,更容易在容器中迭代元素。例如:vectorMyClass *j = any.second ;
这样的行:P
我理解 auto,但为什么要使用 const auto&?循环中不能编辑变量吗?【参考方案4】:
神奇在于Boost.Range's map_values
adaptor:
#include <boost/range/adaptor/map.hpp>
for(auto&& i : foo | boost::adaptors::map_values)
i->bar();
它被正式称为“基于范围的 for 循环”,而不是“foreach 循环”。 :)
【讨论】:
我会写auto const&&
。
@Cheersandhth.-Alf 我想你的意思是auto const &&i
:)
@Xeo /基于范围的for循环/。我知道。我一定是看 SO 标签太久了…… 6_9 无论如何,谢谢!这正是我一直在寻找的。你能解释一下为什么那里的管道是有效的吗?那是按位or
,对吧?
@Blacklight:Boost.Range 的适配器使operator|
过载,以使链接更容易:map | map_values | filtered(pred) | transformed(blub) | reversed
。 :)
@Blacklight: It's all there in the documentation! :)以上是关于我可以使用基于范围的 for 循环轻松迭代地图的值吗?的主要内容,如果未能解决你的问题,请参考以下文章