我正在尝试分区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;} );
}
编译器报错p1
和p2
的函数__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