【问题标题】:Can I easily iterate over the values of a map using a range-based for loop?我可以使用基于范围的 for 循环轻松迭代地图的值吗?
【发布时间】: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]:stackoverflow.com/questions/6963894/…
  • @LyubomirVasilev:不,那只是询问如何在一般地图上迭代范围。这个问题询问如何仅对值进行专门迭代。
  • @Xeo 啊,我明白了。我忽略了这一点。

标签: c++ dictionary for-loop c++11 key-value


【解决方案1】:

由于C++20,您可以将范围适配器std::views::valuesRanges 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]]属性。见这里stackoverflow.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 语法特性,更容易在容器中迭代元素。例如:vector vec{0, 1, 2 ,3, 4, 5, 6, 7, 8, 9};现在在 c++11 中,您可以编写如下代码:for(auto any : vec) { cout
    • 嗯……这不是很有帮助,因为我在发布之前就知道基于范围的循环……我的问题,@Xeo 已经回答了,是关于如何仅遍历地图的值,没有像MyClass *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&amp;&amp;
    • @Cheersandhth.-Alf 我想你的意思是auto const &amp;&amp;i :)
    • @Xeo /基于范围的for循环/。我知道。我一定是看 SO 标签太久了…… 6_9 无论如何,谢谢!这正是我一直在寻找的。你能解释一下为什么那里的管道是有效的吗?那是按位or,对吧?
    • @Blacklight:Boost.Range 的适配器使operator| 过载,以使链接更容易:map | map_values | filtered(pred) | transformed(blub) | reversed。 :)
    猜你喜欢
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 2017-03-20
    • 2011-10-20
    • 1970-01-01
    • 2012-08-25
    • 2022-01-14
    相关资源
    最近更新 更多