C++ 如何使用boost::joined\u range实现范围适配器
以下是基于以下各项的量程适配器示例: 到目前为止,我所有的尝试都以一大堆编译器错误而告终,我还没有展示这些尝试,因为我可能已经走远了。我不知道这是否可能,但有人能帮我吗 最终编辑(解决方案是在基类之前初始化范围)C++ 如何使用boost::joined\u range实现范围适配器,c++,boost,boost-range,C++,Boost,Boost Range,以下是基于以下各项的量程适配器示例: 到目前为止,我所有的尝试都以一大堆编译器错误而告终,我还没有展示这些尝试,因为我可能已经走远了。我不知道这是否可能,但有人能帮我吗 最终编辑(解决方案是在基类之前初始化范围) #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 模板 结构先初始化我 { 首先初始化_me_(typename boost::range::joined_range j) :j_范围(j) {} typename boost::range::joined_ran
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
模板
结构先初始化我
{
首先初始化_me_(typename boost::range::joined_range j)
:j_范围(j)
{}
typename boost::range::joined_range j_range;
};
模板
类别排列范围:
先初始化公共的“我”,
公共boost::迭代器范围<
boost::置换迭代器<
typename boost::range\u迭代器<
boost::range::joined_range>::type,
typename boost::range\u迭代器::type>>
{
使用value\u type=typename boost::range\u value::type;
使用替换的迭代器=boost::置换迭代器<
typename boost::range\u迭代器<
boost::range::joined_range>::type,
typename boost::range_迭代器::type>;
使用base_t=boost::iterator_range;
首先使用init=initialize\u me\u;
公众:
排列范围(常数范围1和r1、常数范围2和r2、常数索引和i)
:init(boost::join(r1,r2)),
base_t(替换了迭代器(boost::begin(init::j_range)),
boost::begin(i)),
替换了迭代器(boost::end(init::j_range),
boost::end(i)))
{}
};
模板
排列范围
置换(常数范围1和r1、常数范围2和r2、常数索引和i)
{
返回置换_范围(r1,r2,i);
}
int main()
{
std::向量v1{1,2,3};
std::向量v2{4,5,6};
列表索引器{1,3,5};
复制(置换(v1,v2,索引器),
std::ostream_迭代器(std::cout,“”);
}
要加入两个范围,请使用boost::join
:
#include <boost/range/join.hpp>
boost::copy(permutation(boost::join(v1, v2), indexer), ...
#包括
复制(置换(boost::join(v1,v2),索引器)。。。
但是将您的
范围
参数更改为通过常量引用而不是非常量引用传递。没有理由要求这些参数的可修改版本,因为您实际上并没有排列它们的内容。谢谢,我还意识到如果我想的话,我可以将boost::join
放在排列
内部保留permutation(v1,v2,indexer)
语法。然而,我最初的目标是将permutation\u范围
更改为使用boost::join
(不知道这是否可行)。这将更加困难。你的置换范围
需要有一个它创建的合并范围的副本-它需要为它创建的替换的迭代器
对象传递相同的r
。在初始化基类之前,该范围必须存在。这是可以解决的,但你也有添加的语法有效的“可选”参数(v2
)的复杂性出现在参数列表的中间。如果调用方想要加入范围,让调用方负责并保持你的界面简单,只关注一件事。对界面有好处,非常感谢你的帮助。在你的评论之后,我能够想出一些东西(见编辑中的问题)。但是,如何在初始化基类之前使范围存在?我从两个类继承了一个解决方案(请参见最终编辑)。再次感谢!
int main()
{
std::vector<int> v1{1, 2, 3};
std::vector<int> v2{4, 5, 6};
std::list<int> indexer{1, 3, 5};
boost::copy(permutation(v1, v2, indexer),
std::ostream_iterator<int>(std::cout, " "));
}
#include <boost/range/join.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <vector>
#include <list>
#include <iterator>
#include <iostream>
template <typename R1, typename R2>
struct initialize_me_first
{
initialize_me_first(typename boost::range::joined_range<const R1, const R2> j)
: j_range(j)
{}
typename boost::range::joined_range<const R1, const R2> j_range;
};
template <typename Range1, typename Range2, typename Index>
class permutation_range :
public initialize_me_first<Range1, Range2>,
public boost::iterator_range<
boost::permutation_iterator<
typename boost::range_iterator<
boost::range::joined_range<Range1, Range2>>::type,
typename boost::range_iterator<Index>::type>>
{
using value_type = typename boost::range_value<Range1>::type;
using replaced_iterator = boost::permutation_iterator<
typename boost::range_iterator<
boost::range::joined_range<Range1, Range2>>::type,
typename boost::range_iterator<Index>::type>;
using base_t = boost::iterator_range<replaced_iterator>;
using init = initialize_me_first<Range1, Range2>;
public:
permutation_range(const Range1& r1, const Range2& r2, const Index& i)
: init(boost::join(r1, r2)),
base_t(replaced_iterator(boost::begin(init::j_range),
boost::begin(i)),
replaced_iterator(boost::end(init::j_range),
boost::end(i)))
{}
};
template <typename Range1, typename Range2, typename Index>
permutation_range<const Range1, const Range2, const Index>
permutation(const Range1& r1, const Range2& r2, const Index& i)
{
return permutation_range<const Range1,
const Range2,
const Index>(r1, r2, i);
}
int main()
{
std::vector<int> v1{1, 2, 3};
std::vector<int> v2{4, 5, 6};
std::list<int> indexer{1, 3, 5};
boost::copy(permutation(v1, v2, indexer),
std::ostream_iterator<int>(std::cout, " "));
}
#include <boost/range/join.hpp>
boost::copy(permutation(boost::join(v1, v2), indexer), ...