分区一个boost::range::转换后的范围适配器



我正在尝试分区boost::range::transformed适配器:

#include <boost/range.hpp>
#include <boost/range/algorithm/partition.hpp>
#include <boost/range/algorithm/transform.hpp>
#include <boost/range/any_range.hpp>
#include <boost/range/adaptor/transformed.hpp>
using boost::adaptors::transformed;
void foo()
{
    boost::any_range<int,
                     boost::forward_traversal_tag,
                     int&,
                     std::ptrdiff_t> r;
    auto t = r | transformed( [](int) {return 0;} );
    auto p = boost::range::partition(t, [](int) {return true;} );
    std::vector<int> v;
    auto t2 = r | transformed( [](int) {return 0;} );
    auto p2 = boost::range::partition(t2, [](int) {return true;} );
}

编译器报错p1p2的函数__partition不能接受boost::iterators__transform_iterator。完整的错误信息是

In file included from /opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/algorithm:62:0,
                 from /tmp/boost_1_59_0/boost/iterator/iterator_concepts.hpp:29,
                 from /tmp/boost_1_59_0/boost/range/concepts.hpp:20,
                 from /tmp/boost_1_59_0/boost/range/size_type.hpp:20,
                 from /tmp/boost_1_59_0/boost/range/size.hpp:21,
                 from /tmp/boost_1_59_0/boost/range/functions.hpp:20,
                 from /tmp/boost_1_59_0/boost/range.hpp:18,
                 from range_partition.cpp:1:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h: In instantiation of ‘_BIter std::partition(_BIter, _BIter, _Predicate) [with _BIter = boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>; _Predicate = foo()::<lambda(int)>]’:
/tmp/boost_1_59_0/boost/range/algorithm/partition.hpp:34:65:   required from ‘typename boost::range_iterator<C>::type boost::range::partition(ForwardRange&, UnaryPredicate) [with ForwardRange = boost::range_detail::transformed_range<foo()::<lambda(int)>, boost::range_detail::any_range<int, boost::iterators::forward_traversal_tag, int&, long int> >; UnaryPredicate = foo()::<lambda(int)>; typename boost::range_iterator<C>::type = boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>]’
range_partition.cpp:22:66:   required from here
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:4509:43: error: no matching function for call to ‘__partition(boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>&, boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>&, foo()::<lambda(int)>&, std::__iterator_traits<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>, true>::iterator_category)’
          std::__iterator_category(__first));
                                           ^
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:4509:43: note: candidates are:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:1462:5: note: template<class _ForwardIterator, class _Predicate> _ForwardIterator std::__partition(_ForwardIterator, _ForwardIterator, _Predicate, std::forward_iterator_tag)
     __partition(_ForwardIterator __first, _ForwardIterator __last,
     ^
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:1462:5: note:   template argument deduction/substitution failed:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:4509:43: note:   cannot convert ‘std::__iterator_category<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default> >((*(const boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>*)(& __first)))’ (type ‘std::__iterator_traits<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>, true>::iterator_category {aka boost::iterators::detail::iterator_category_with_traversal<std::input_iterator_tag, boost::iterators::forward_traversal_tag>}’) to type ‘std::forward_iterator_tag’
          std::__iterator_category(__first));
                                           ^
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:1487:5: note: template<class _BidirectionalIterator, class _Predicate> _BidirectionalIterator std::__partition(_BidirectionalIterator, _BidirectionalIterator, _Predicate, std::bidirectional_iterator_tag)
     __partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
     ^
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:1487:5: note:   template argument deduction/substitution failed:
/opt/rh/devtoolset-3/root/usr/include/c++/4.9.2/bits/stl_algo.h:4509:43: note:   cannot convert ‘std::__iterator_category<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default> >((*(const boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>*)(& __first)))’ (type ‘std::__iterator_traits<boost::iterators::transform_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<foo()::<lambda(int)>, int>, boost::range_detail::any_iterator<int, boost::iterators::forward_traversal_tag, int&, long int, boost::any_iterator_buffer<64ul> >, boost::iterators::use_default, boost::iterators::use_default>, true>::iterator_category {aka boost::iterators::detail::iterator_category_with_traversal<std::input_iterator_tag, boost::iterators::forward_traversal_tag>}’) to type ‘std::bidirectional_iterator_tag’
          std::__iterator_category(__first));

我很失落,找不到解决这个问题的办法。

转换后的范围不是可变序列。

不能对这样的范围进行分区(因为不能交换元素)。

您可以查看partition_copy,在这种情况下,您应该有一个目标迭代器来接收分区范围。

通过一点工作,看起来你应该能够制作一个Boost Range style适配器(参见文档扩展:http://www.boost.org/doc/libs/1_59_0/libs/range/doc/html/range/reference/extending/method_3.html),如果你真的坚持在第一个例子中有partitioned

样本

这是我建议的"一半"解决方案:方便而不需要太多的努力(c++11)

Live On Coliru

#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/algorithm_ext.hpp>
#include <boost/range/any_range.hpp>
#include <boost/range/adaptors.hpp>
using boost::adaptors::transformed;
namespace {
    // convenience wrapper
    template <typename Range, typename Predicate, typename OutIt1, typename OutIt2>
        std::pair<OutIt1, OutIt2> partition_copy(Range const& range, OutIt1 out1, OutIt2 out2, Predicate&& predicate) {
            return std::partition_copy(
                    boost::begin(range), boost::end(range),
                    out1, out2,
                    std::forward<Predicate>(predicate));
        }
}
#include <iostream>
int main()
{
    std::vector<int> demo { 1,2,7,3,-9,42 };
    std::vector<int> even, odd;
    partition_copy(
            demo | transformed( [](int i) {return i+1;} ), 
            back_inserter(even), back_inserter(odd),
            [] (int i) { return 0 == i%2; }
        );
    // output
    boost::copy(even, std::ostream_iterator<int>(std::cout << "even : ", " "));
    boost::copy(odd,  std::ostream_iterator<int>(std::cout << "nodd  : ", " "));
}

打印

even : 2 8 4 -8 
odd  : 3 43 

相关内容

  • 没有找到相关文章

最新更新