具有多个容器的循环范围

新手上路,请多包涵

假设我有 2 个(或更多)容器要同时迭代 - 例如,计算两个向量的点积:

 std::vector<double> vector1;
std::vector<double> vector2;    // identical size to vector1

在两个(或所有)容器上同时指定 range-for 循环的首选 C++11 方法是什么?它是否涉及在 range-for 循环中选择一个容器/迭代器来编写速记(即 for ( auto i : c ) ),而所有其他容器/迭代器必须长期处理?是否有任何理由将来无法扩展语法以支持两个/所有容器的简写,如下所示……这看起来真的很可读:

 double dotProduct( 0.0 );
for ( auto const & value1 : vector1, auto const & value2 : vector2 )  // illegal!
{
    dotProduct += value1*value2;
}

原文由 omatai 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 526
1 个回答

在其他(通常是函数式)语言中,这是通过使用名为 zip 的函数来完成的。例如,Python 有一个内置的 zip 迭代其参数并返回一个元组:

 for i in zip( [1,2,3], (1,2,3), { 0:0, 1:1, 2:2 } ):
    l,t,d = i
    print("list item: %d, tuple item %d, dict item %d" % (l,t,d) )

您可以使用 C++ 中的范围库来获得该功能,例如 Boost.RangeEric Niebler 的 rangev3 。不幸的是,范围没有在 C++17 标准中投票,但我永远不会在没有范围库的情况下开始一个项目。在 Boost.Range 中,该函数被称为 combine

 #include <boost/range/combine.hpp>
#include <boost/tuple/tuple.hpp>
#include <iostream>
#include <vector>
#include <list>

int main(int, const char*[])
{
    using namespace boost;

    std::vector<int> const v{0,1,2,3,4};
    std::list<char> const  l{'a', 'b', 'c', 'd', 'e'};

    for(auto const& i: combine(v, l))
    {
        int ti;
        char tc;
        boost::tie(ti,tc) = i;
        std::cout << '(' << ti << ',' << tc << ')' << '\n';
    }

    return 0;
}

使用 C++17,您可以用结构化绑定替换 std::tie 并用 std::tie 删除那种不寻常的“初始化”。

   for(auto const& [ti,tc] : boost::combine(v, l)) {
     std::cout << '(' << ti << ',' << tv << ')' << '\n';
  }

虽然我很遗憾 C++17 中没有包含范围,但我认为结构化绑定是一个巨大的进步,并将严重改变代码的编写方式。在标准中包含范围将使它们更受欢迎,并将它们从许多人反对的第三方库提升为 C++ 程序员应该知道的标准特性。

原文由 Jens 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题