C++ 在多个集合上循环时写回迭代器

C++ 在多个集合上循环时写回迭代器,c++,boost,collections,iterator,boost-foreach,C++,Boost,Collections,Iterator,Boost Foreach,我想使用迭代器遍历两个集合,根据涉及另一个集合的(足够复杂的)算法修改其中一个集合。考虑下面的最小例子: #include <iostream> #include <vector> #include <boost/foreach.hpp> #include <boost/range/combine.hpp> #include <boost/tuple/tuple.hpp> // tie using namespace std; usin

我想使用迭代器遍历两个集合,根据涉及另一个集合的(足够复杂的)算法修改其中一个集合。考虑下面的最小例子:

#include <iostream>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/range/combine.hpp>
#include <boost/tuple/tuple.hpp> // tie
using namespace std;
using namespace boost;

int main(void) {
  // input data; never mind how these get filled
  int aa[] = {2, 3, 5, 8, 13, 21};
  int bb[] = {1, 0, 1, 1,  0,  1};
  vector<int> a (&aa[0], &aa[sizeof(aa)/sizeof(aa[0])]);
  vector<int> b (&bb[0], &bb[sizeof(bb)/sizeof(bb[0])]);

  // output storage; assume it has always correct dim.
  vector<int> c (a.size());

  // iterate through two coll., reading from both
  int p, q;
  BOOST_FOREACH (tie(p,q), combine(a,b)) { // loop1
    cout << p << "*" << q << "=" << p*q << endl;
  }

  // iterate through one coll., writing to it
  BOOST_FOREACH (int& r, c) { // loop2
    r = 42;
  }

  // iterate through two coll., reading from one, writing to the other?
  BOOST_FOREACH (??? p, s ???, combine(a,c)) { // loop3
    s = p * 2;
  }

  return 0;
}
#包括
#包括
#包括
#包括
#包括//领带
使用名称空间std;
使用名称空间boost;
内部主(空){
//输入数据;不管这些数据是如何填写的
int aa[]={2,3,5,8,13,21};
int-bb[]={1,0,1,1,0,1};
向量a(&aa[0],&aa[sizeof(aa)/sizeof(aa[0]));
向量b(&bb[0],&bb[sizeof(bb)/sizeof(bb[0]));
//输出存储;假定它始终具有正确的dim。
向量c(a.size());
//迭代两个列,从两个列中读取
int p,q;
BOOST_FOREACH(tie(p,q),combine(a,b)){//loop1

在我看来,您过度使用了
BOOST\u FOREACH
,几乎达到了令人震惊的程度。就像
std::FOREACH
,这应该是您最后选择的算法之一

您的第三个循环几乎肯定应该使用
std::transform
编写。它旨在获取一个输入范围,对其进行转换,并将结果存储到一个输出范围(或者获取两个输入范围,将它们合并,并将结果放入第三个,例如在您第一次(错误)使用BOOST_FOREACH时)

使用此选项,您的第三个循环将显示如下内容:

// c[i] = a[i] * 2, i = 0..N-1
std::transform(begin(a), end(a), begin(c), [](int i) { return i * 2; });
至于你的第二个,看起来你真的想要
std::fill\n

std::fill_n(begin(c), end(c), 42);

现在,基于范围的东西(例如中的算法)确实可以通过替换每个
begin(X)、end(X)来简化这一过程
与单个参数配对。尽管如此,它们已经明显优于BOOST\u FOREACH版本,具有杂项
tie
s和
combined
s,以尝试将方形销钉压入圆孔。

zip\u范围的值类型是对元素的一组引用:

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

int main(int ac,char* av[])
{
  // input data; never mind how these get filled
  int aa[] = {2, 3, 5, 8, 13, 21};
  int bb[] = {1, 0, 1, 1,  0,  1};
  std::vector<int> a(boost::begin(aa), boost::end(aa));
  std::vector<int> const b(boost::begin(bb), boost::end(bb));

  // output storage; assume it has always correct dim.
  std::vector<int> c (a.size());

  typedef boost::tuple<int const&, int&> val_t;
  BOOST_FOREACH(val_t const& v, boost::combine(a, c)) {
    v.get<1>() = v.get<0>() * 2;
  }
}
#包括
#包括
#包括
#包括
#包括
#包括
int main(int ac,char*av[])
{
//输入数据;不管这些数据是如何填写的
int aa[]={2,3,5,8,13,21};
int-bb[]={1,0,1,1,0,1};
std::向量a(boost::begin(aa),boost::end(aa));
std::vector const b(boost::begin(bb),boost::end(bb));
//输出存储;假定它始终具有正确的dim。
向量c(a.size());
typedef boost::元组值;
增压器(val_t const&v,增压器::联合收割机(a,c)){
v、 get()=v.get()*2;
}
}

您很容易震惊…;-)如果算法需要周围的上下文,使用简单循环可能比将所有内容重构为包含上下文的对象更具可读性——我认为这取决于大小写。这里的示例只是为了说明问题。@RolKau:在有些情况下,循环可以作为合理的替代方法我也一样,它们真的很不寻常——你在这里还没有展示过这样的例子。所以,线索是,既然不能初始化一对引用,那么就得到这对引用,然后使用它返回的引用!(对于这个问题的未来读者:你也可以声明
int&s=v.get();
)这让我感到震惊“这是一把足够大的锤子,可以把你的圆钉子敲入一个方孔".你的问题可能需要一些认真的清理--特别是,你在解释你在第三个循环中真正想要实现的目标方面做得太少了,以至于现在几乎不可能给出一个确切的答案--我已经给出了答案,但对于你的第三个循环,除了对它的猜测之外,不可能给出更多你真正想要的。