在ref / cref范围内同时迭代

时间:2016-04-07 20:56:57

标签: c++ c++11 boost

我有一个带两个整数向量的函数。第一个向量作为引用传递,第二个向量作为const的引用传递。我想同时迭代两个向量,并更新第一个向量。如下所示:

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

void foo(std::vector<int>& a, std::vector<int> const& b) 
{
        boost::tuple<int&, int const&> x;
        BOOST_FOREACH(x, boost::combine(a,b)) {
           int& v1 = x.get<0>();
           int const& v2 = x.get<1>();
           v1 = v1 + v2 + 5;
        }

}

int main(int argc, char **argv) 
{   
  std::vector<int> a(3,10);
  std::vector<int> b(3,10);

  foo(a,b);
  for (int v : a) {
    std::cout << v << std::endl;   
  }
  return 0;
}

我遇到的问题是迭代两个范围,其中一个是ref,另一个是ref const。如何正确使用boost:combine / for循环?感谢。

2 个答案:

答案 0 :(得分:5)

至少如果我正确阅读Boost内容,你似乎想要类似的内容:

std::transform(a.begin(), a.end(), 
               b.begin(),
               a.begin(),
               [] (int x, int y) { return x + y + 5; });

现在,它使用的是C ++ 11。如果你需要它而没有C ++ 11,你无疑可以使用Boost Lambda来完成同样的事情,或者你可以自己编写一个函数对象:

struct combine { 
    int operator()(int x, int y) { return x + y + 5; }
};

void foo(std::vector<int>& a, std::vector<int> const & b)
{       
    std::transform(a.begin(), a.end(), 
                   b.begin(),
                   a.begin(),
                    combine());
}

另请注意,std::vector<int>& const b不正确。你几乎肯定打算:std::vector<int> const &b代替。使用const后面的& const,它表示引用本身为const。之前移动它意味着引用引用的是const。前者没有任何意义(你不能将{{1}}应用于引用;在const引用的概念完全有意义的范围内,每个引用都是const)。

答案 1 :(得分:1)

您没有充分利用C ++ 11的类型演绎。此外,当迭代整数时,通过引用访问它们毫无意义。

您的代码未编译的原因有两个:1。您不能使用引用默认构造元组,以及2.当它具有const引用时,您无法更改其值。无论如何boost::tuple<int&, int const&> x;是不必要的。

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

void foo(std::vector<int>& a, std::vector<int> const& b)
{
   for(auto x : boost::combine(a,b))
      x.get<0>() += x.get<1>() + 5;
}

int main()
{
   std::vector<int> a(3,10);
   std::vector<int> b(3,10);
   foo(a,b);
   for (auto v : a)
      std::cout << v << std::endl;
}

当然你真的应该使用std::transform,但这表明如果你只是更多地利用C ++ 11,你的代码就会起作用:)