【问题标题】:Iterating through map keys in C++ 17在 C++ 17 中遍历映射键
【发布时间】:2020-04-16 13:24:52
【问题描述】:

我正在寻找一种在 C++ 17 中遍历映射键的方法。我现在想到的方法是基于这个 question 的答案,方法如下所示。

for (auto const& [i, val] : myMap)
...

但是,我不需要使用值val,我只需要值i。因此,这段代码... 不包含对值val 的任何调用。因此,每当我编译代码时,都会出现以下警告消息:

warning: unused variable ‘val’ [-Wunused-variable]
         for (auto const& [i, val] : myMap){
                                  ^

我想要的是找到一种方法来迭代(仅)地图的键,而忽略值。有人知道怎么做吗?

【问题讨论】:

    标签: c++ c++17


    【解决方案1】:

    两种选择:

    1. @πάνταῥεῖ 的answer 的远程版本:

      for (auto const& pair : myMap) {
          auto key = pair.first;
          // etc. etc.
      }
      
    2. 使用ranges-v3 library(或C++20 中的std::ranges)通过将myMap.begin()myMap.end() 投影到其第一个坐标来调整范围。然后你会写这样的东西:

      for (auto key : keys_of(myMap) ) {
          // etc. etc.
      }
      

      如果keys_of() 实现了所有键,您可以在没有范围的情况下执行此操作,但对于较大的地图来说这可能会很昂贵。

      (如果你有奇怪、沉重的按键,那么const auto& key 而不是auto key。)

    【讨论】:

      【解决方案2】:

      有人知道怎么做吗?

      当然!您可以只使用带有迭代器的传统 for 循环:

      for(auto it = myMap.begin(); it != myMap.end(); ++it) {
          auto i = it->first;
          // ...
      }
      

      【讨论】:

      • 谢谢。但我在想类似的东西:for (auto key : myMap.keys()) 类似于 Java。
      • @MatheusDiógenesAndrade 在 C++ 中没有这样的等价物。
      【解决方案3】:

      如何在_ 中使用类似Go 的未使用变量声明:

      for(auto const& [i, _] : myMap)
      ...
      

      【讨论】:

      • 这应该有什么帮助? warning: unused variable '_'
      【解决方案4】:

      您可以通过转换为 void 来避免未使用的警告:

      for (auto const& [key, val] : m) {
        (void)val;  // To avoid unused warnings
      
        // use key
      }
      

      【讨论】:

      • 谢谢,很有趣。你能向我解释为什么它有效吗?因为我不知道这个“(void) val”到底是什么意思。
      • @MatheusDiógenesAndrade What does casting to void really do?
      【解决方案5】:

      for(auto const & pair : myMap) 由于 map 以 std::pair 格式在内部存储元素,因此您可以访问 通过写元素,pair.first;对于密钥或对。第二;为了价值。

      【讨论】:

      • 这是@einpoklum 提出的解决方案。不过谢谢你的回复。
      【解决方案6】:
      for (auto& [key, std::ignore] : m) {
        // use key
      }
      

      【讨论】:

      • 欢迎来到 SO。请编辑您的答案并添加一些关于代码的描述。不鼓励仅使用代码回答。
      • 结构化绑定必须是标识符;这是一个声明,不是赋值或引用绑定。
      • 至少确保你的代码在转储之前编译。 (It doesn't.)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-11
      • 1970-01-01
      • 2012-05-14
      相关资源
      最近更新 更多