我想使用 boost::range 来实现类似于 NumPy 和 Matlab 中可用的“花式索引”的东西。具体来说,我想使用另一个容器的元素作为索引来选择一个可索引容器的某些元素。例如,可以在 Python 中执行以下操作:
>>> squares = numpy.arange(10)**2 # Step 1 - setup squares
>>> indices = numpy.array([1,3,4]) # Step 2 - setup indices
>>> squares[indices] # Step 3 - fancy indexing
array([ 1, 9, 16])
在 C++ 中,使用 boost::range,我认为上面的代码看起来像这样:
#include "sampled.hpp"
#include <boost/assign/std/vector.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/counting_range.hpp>
#include <iostream>
#include <vector>
using namespace boost;
using namespace boost::adaptors;
using namespace boost::assign;
using namespace boost::lambda;
using namespace std;
int main(int argc, char** argv)
{
// Step 1 - setup squares
vector<int> squares;
push_back(
squares,
counting_range(1,11) | transformed(ret<int>(_1 * _1))
);
// Step 2 - setup indices
vector<size_t> indices;
indices += 1,3,4;
// Step 3 - fancy indexing
for_each(
squares | sampled(indices),
cout << _1 << constant(" ")
);
return 0;
}
由于现有范围适配器(boost::adaptor::indexed)已经使用了名称“indexed”,因此我在上面的代码中将尚未实现的索引适配器称为“sampled”。
有谁知道这样的适配器是否已经存在于某个地方的 boost 中,或者是否有他们愿意分享的实现?我已经开始尝试自己实现它,首先编写一个“sampled_iterator”(使用 iterator_adaptor),然后编写一个“sampled_range”(使用 iterator_range),但我发现它非常棘手。