gpt4 book ai didi

c++ - boost::range 库的自定义范围

转载 作者:太空狗 更新时间:2023-10-29 21:40:42 25 4
gpt4 key购买 nike

我正在使用 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/non-const 迭代器
  • 它使用 Boost Range 特征(range_mutable_iterator<> 等)而不是假设嵌套 typedef 的硬编码。这允许事情与其他范围一起工作(例如 std::array<> 甚至 int (&)[] )。

  • 用户定义的转换运算符使用 boost::copy_range<>出于类似的原因

关于c++ - boost::range 库的自定义范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30460003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com