boost::range库的自定义范围
Custom range for boost::range library
我正在使用boost::range库编写过滤器和映射算法:
template <class Range> struct Converter
{
Converter(const Range& p_range) : m_range(p_range) {}
template<class OutContainer> operator OutContainer() const
{
return {m_range.begin(), m_range.end()};
}
private:
Range m_range;
};
template<class Range> Converter<Range> convert(const Range& p_range) { return {p_range}; }
template<class Range, class Fun> auto map(Range&& p_range, Fun&& p_fun)
{
return convert(p_range | boost::adaptors::transformed(p_fun));
}
template<class Range, class Pred> auto filter(Range&& p_range, Pred&& p_pred)
{
return convert(p_range | boost::adaptors::filtered(p_pred));
}
现在我可以这样使用它们:
std::vector<int> l_in = {1, 2, 3, 4, 5};
std::vector<int> l_tmp_out = filter(l_in, [](int p){ return p < 4; });
std::vector<int> l_out = map(l_tmp_out, [](int p){ return p + 5; });
我也想这样写代码:
map(filter(l_in, [](int p){ return p < 4; }), [](int p){ return p + 5; });
不幸的是,我的Converter类没有与boost::range算法组合在一起,所以这个例子无法编译。我正在寻找一个合适的方法来改变这一点。
我跟随@sehe链接,结果证明我所要做的就是将这四行添加到Converter类中:
using iterator = typename Range::iterator;
using const_iterator = typename Range::const_iterator;
auto begin() const { return m_range.begin(); }
auto end() const { return m_range.end(); }
以下是我的看法:
Live On Coliru
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>
#include <vector>
namespace MyRange {
template <typename R> struct Proxy {
Proxy(R&& r) : _r(std::move(r)) {}
Proxy(R const& r) : _r(r) {}
template <typename OutContainer> operator OutContainer() const {
return boost::copy_range<OutContainer>(_r);
}
using iterator = typename boost::range_mutable_iterator<R>::type;
using const_iterator = typename boost::range_const_iterator<R>::type;
auto begin() const { return range_begin(_r); }
auto end() const { return range_end(_r); }
auto begin() { return range_begin(_r); }
auto end() { return range_end(_r); }
private:
R _r;
};
template <typename R> auto make_proxy(R&& r) { return Proxy<R>(std::forward<R>(r)); }
template <typename Range, typename Fun> auto map(Range&& p_range, Fun&& p_fun) {
return make_proxy(std::forward<Range>(p_range) | boost::adaptors::transformed(std::forward<Fun>(p_fun)));
}
template <typename Range, typename Pred> auto filter(Range&& p_range, Pred&& p_pred) {
return make_proxy(std::forward<Range>(p_range) | boost::adaptors::filtered(std::forward<Pred>(p_pred)));
}
}
int main() {
using namespace MyRange;
{
std::vector<int> l_in = {1, 2, 3, 4, 5};
std::vector<int> l_tmp_out = filter(l_in, [](int p){ return p < 4; });
std::vector<int> l_out = map(l_tmp_out, [](int p){ return p + 5; });
boost::copy(l_out, std::ostream_iterator<int>(std::cout << "nfirst:t", "; "));
}
{
boost::copy(
map(
filter(
std::vector<int> { 1,2,3,4,5 },
[](int p){ return p < 4; }),
[](int p){ return p + 5; }),
std::ostream_iterator<int>(std::cout << "nsecond:t", "; "));
}
}
打印
first: 6; 7; 8;
second: 6; 7; 8;
指出- 它更准确地使用
std::forward<>
- 使用const/非const迭代器
它使用Boost Range特性(
range_mutable_iterator<>
等)而不是硬编码假设嵌套类型定义。这允许事物与其他范围(例如std::array<>
甚至int (&)[]
)一起工作。用户自定义转换操作符出于类似的原因使用
boost::copy_range<>
相关文章:
- 创建包装升压适配器的自定义范围类
- C++11:没有复制构造函数的自定义基于范围的循环
- 使自定义范围 v3 视图可管道化
- 如何自定义设置随机的范围?
- 如何使用提升范围将自定义迭代器封装在函数中
- 基于范围的 for 循环,用于包含C++中的指针的自定义链表,仅返回对象
- 带有自定义对象的C 范围循环
- 基于范围的自定义迭代器:constness问题
- 在自定义容器类上反转基于范围的 for 循环
- 如何实现我的自定义范围循环
- 具有自定义步骤的循环的C 范围
- 基于自定义范围的迭代器,用于矢量的模板向量
- "stoi"没有在此范围内声明,即使添加 -std=c++0x 和自定义函数,仍然适用
- 基于自定义容器范围的迭代
- 如何在c++中为字符串指定自定义值范围
- 范围互斥锁的自定义RAII c++实现
- 带有自定义类的范围循环(矢量的简单版本<string>,使用分配器)
- 可以定义在系统范围内使用的自定义URI方案
- 为所有游标id在系统范围内设置自定义游标
- boost::range库的自定义范围