我想使用迭代器遍历两个集合,根据涉及另一个的(足够复杂的)算法修改一个集合。请考虑以下最小示例:
#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;
}
如何在???
之间声明部分(或以其他方式更改loop3中的参数)?
答案 0 :(得分:1)
zip_range
的值类型是元素引用的元组:
#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;
}
}
答案 1 :(得分:0)
IMO,你过度使用BOOST_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);
现在,基于范围的某些内容(例如Boost Range中的算法)可以通过用单个参数替换每个begin(X), end(X)
对来使这更简单一些。尽管如此,这些已经明显优于具有其他tie
和combine
s的BOOST_FOREACH版本,以尝试将方形钉固定成圆孔。