【问题标题】:Create a template to iterate map in C++11 like C++17's structured bindings创建一个模板以在 C++11 中迭代映射,如 C++17 的结构化绑定
【发布时间】:2020-12-05 14:54:12
【问题描述】:

C++17 为我们带来了一种更好的方式来使用Structured binding 迭代map,如example 所示。

我一定会使用 C++14,但有很多重复的代码在地图上进行迭代。

在 C++14 中是这样的:

for (auto const& item : myMap)
{
    std::string key = x.first;
    int value = x.second;
    //Code...
}

有没有办法创建模板/define/using/其他任何东西,让我可以方便地以这种方式进行迭代,但仍可编译为 C++14 应用程序?强>

for( auto const& [key, value] : myMap)
{
    //Code...
} 

【问题讨论】:

    标签: c++ c++14


    【解决方案1】:

    在 C++20 之前,您无法在基于范围的循环内初始化变量,所以最好的选择,我可以看到使用这样的宏:

    #define STRUCTURED_BINDING(a, b, map_item) \
             const auto &a = map_item.first; \
             const auto &b = map_item.second;
    

    那么在你的代码中,你可以这样写:

    for(const auto& item: a)
    {
        STRUCTURED_BINDING(fst, snd, item);
        std::cout << fst << " " << snd << std::endl;
    }
    

    您可以改进此宏以与元组 (get&lt;0&gt;, get&lt;1&gt;, ...) 一起使用,重写宏以使用可变参数。

    【讨论】:

    • 或者你可以使用std::tie
    • 很好...但是如果键和值在 for 循环的范围内应该是非常量的呢?或者也可能只是原始类型的副本?无论如何+1 用于宏......在我看来,它可以扩展到其他情况!
    【解决方案2】:

    也许你可以在这里破解一些东西 - 但你最好不要。

    虽然@Midren 的建议确实有效,但我想建议您不要这样做。

    C++14 循环确实比 C++17 中的更冗长。但是 - 它很容易理解和公认。引入宏或自定义小工具 - 可能会为您节省一些字符,但会花费您 可读性可维护性。如果您的基于宏的方法变得非常流行,那么可读性将不再是问题,并且可维护性几乎是微不足道的(只需确保每个人都使用相同的小工具而不是重新定义它,在更大的项目中)。但是 - 这永远不会发生,因为我们已经有了 C++17。

    相反,我会调整命名和间距以提高清晰度。例如,假设它是 foo 到 bar 的映射:

    for (auto const& foo_bar_pair : myMap) {
        const auto& foo = foo_bar_pair.first;
        const auto& bar = foo_bar_pair.second;
    
        //Code with `foo` and `bar`
    }
    

    【讨论】:

      猜你喜欢
      • 2015-08-21
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-26
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多