3

给定

auto cstr = "quick brown fox";

我们有一组适配器只是为了分割单词然后尝试将它们显示为格式化范围。

auto adaptors = ranges::view::split(' ') | ranges::view::all;

如果 source 是 string_view,那没关系。

auto sv = std::string_view{cstr};
ranges::copy(sv | adaptors, ranges::ostream_iterator(std::cout,";") );

输出:[魔杖盒]

[q,u,i,c,k];[b,r,o,w,n];[f,o,x];

然后尝试使用 view::c_str

auto cstr_rng = ranges::view::c_str(cstr);
// Won't compile
// ranges::copy(cstr_rng | adaptors, ranges::ostream_iterator(std::cout,";") );

错误:[CE]

/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view/split.hpp: In instantiation of 'ranges::v3::split_view<Rng, Fun>::cursor<IsConst>::cursor(ranges::v3::split_view<Rng, Fun>::cursor<IsConst>::fun_ref_t, ranges::v3::iterator_t<Rng>, ranges::v3::sentinel_t<Rng>) [with bool IsConst = true; Rng = ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>; Fun = ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&>; ranges::v3::split_view<Rng, Fun>::cursor<IsConst>::fun_ref_t = ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&>; ranges::v3::iterator_t<Rng> = ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::adaptor_cursor<const char*, ranges::v3::adaptor_base> >; ranges::v3::sentinel_t<Rng> = ranges::v3::adaptor_sentinel<ranges::v3::unreachable, ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>::sentinel_adaptor>]':
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view/split.hpp:128:69:   required from 'ranges::v3::split_view<Rng, Fun>::cursor<true> ranges::v3::split_view<Rng, Fun>::begin_cursor() const [with int _concept_requires_125 = 42; typename std::enable_if<((_concept_requires_125 == 43) || (ranges::v3::concepts::models<ranges::v3::concepts::Invocable, const Fun&, decltype (ranges::v3::function_objects::begin(declval<T&>())), decltype (ranges::v3::function_objects::end(declval<Rng&>()))>() && ranges::v3::concepts::models<ranges::v3::concepts::Range, const D>())), int>::type <anonymous> = 0; Rng = ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>; Fun = ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&>]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/range_access.hpp:176:13:   required from 'static constexpr decltype (static_cast<const Rng&>(rng).begin_cursor()) ranges::v3::range_access::begin_cursor(Rng&, int) [with Rng = const ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >; decltype (static_cast<const Rng&>(rng).begin_cursor()) = ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >::cursor<true>]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view_facade.hpp:93:51:   required from 'ranges::v3::detail::facade_iterator_t<const D> ranges::v3::view_facade<Derived, C>::begin() const [with D = ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >; int _concept_requires_90 = 42; typename std::enable_if<((_concept_requires_113 == 43) || typename ranges::v3::concepts::Same::same<C, Cur>::type()), int>::type <anonymous> = 0; Derived = ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >; ranges::v3::cardinality Cardinality = (ranges::v3::cardinality)-1; ranges::v3::detail::facade_iterator_t<const D> = ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >::cursor<true> >; typename std::decay<decltype (ranges::v3::range_access::begin_cursor(declval<const D&>(), 42))>::type = ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >::cursor<true>]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/begin_end.hpp:58:17:   required from 'static constexpr I ranges::v3::_begin_::fn::impl_(R&, int) [with R = const ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >; I = ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >::cursor<true> >; int _concept_requires_56 = 42; typename std::enable_if<((_concept_requires_56 == 43) || ranges::v3::concepts::models<ranges::v3::concepts::Iterator, I>()), int>::type <anonymous> = 0]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/begin_end.hpp:76:17:   required from 'constexpr decltype (ranges::v3::_begin_::fn::impl_(r, 42)) ranges::v3::_begin_::fn::operator()(R&) const [with R = const ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >; decltype (ranges::v3::_begin_::fn::impl_(r, 42)) = ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >::cursor<true> >]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/begin_end.hpp:145:56:   [ skipping 6 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/utility/functional.hpp:718:13:   required by substitution of 'template<class Arg, class Pipe> static decltype (pipe(static_cast<Arg&&>(arg))) ranges::v3::pipeable<ranges::v3::view::all_fn>::pipe<Arg, Pipe>(Arg&&, Pipe) [with Arg = ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >; Pipe = ranges::v3::view::all_fn]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/utility/functional.hpp:728:9:   required by substitution of 'template<class Arg, class Pipe, int _concept_requires_726, typename std::enable_if<((_concept_requires_726 == 43) || ((! ranges::v3::is_pipeable<T>()) && ranges::v3::is_pipeable<Pipe>())), int>::type <anonymous> > decltype (ranges::v3::pipeable_access::impl<Pipe>::pipe(static_cast<Arg&&>(arg), pipe)) ranges::v3::operator|(Arg&&, Pipe) [with Arg = ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >; Pipe = ranges::v3::view::all_fn; int _concept_requires_726 = 42; typename std::enable_if<((_concept_requires_726 == 43) || ((! ranges::v3::is_pipeable<T>()) && ranges::v3::is_pipeable<Pipe>())), int>::type <anonymous> = 0]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/utility/functional.hpp:644:17:   required by substitution of 'template<class Arg> decltype (((static_cast<Arg&&>(arg) | ((const ranges::v3::detail::composed_pipe<ranges::v3::view::view<ranges::v3::detail::pipeable_binder<std::_Bind<ranges::v3::view::split_fn(std::_Placeholder<1>, char)> > >, ranges::v3::view::all_fn>*)this)->ranges::v3::detail::composed_pipe<ranges::v3::view::view<ranges::v3::detail::pipeable_binder<std::_Bind<ranges::v3::view::split_fn(std::_Placeholder<1>, char)> > >, ranges::v3::view::all_fn>::pipe0_) | ((const ranges::v3::detail::composed_pipe<ranges::v3::view::view<ranges::v3::detail::pipeable_binder<std::_Bind<ranges::v3::view::split_fn(std::_Placeholder<1>, char)> > >, ranges::v3::view::all_fn>*)this)->ranges::v3::detail::composed_pipe<ranges::v3::view::view<ranges::v3::detail::pipeable_binder<std::_Bind<ranges::v3::view::split_fn(std::_Placeholder<1>, char)> > >, ranges::v3::view::all_fn>::pipe1_)) ranges::v3::detail::composed_pipe<ranges::v3::view::view<ranges::v3::detail::pipeable_binder<std::_Bind<ranges::v3::view::split_fn(std::_Placeholder<1>, char)> > >, ranges::v3::view::all_fn>::operator()<Arg>(Arg&&) const [with Arg = ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/utility/functional.hpp:718:13:   required by substitution of 'template<class Arg, class Pipe> static decltype (pipe(static_cast<Arg&&>(arg))) ranges::v3::pipeable<ranges::v3::detail::pipeable_binder<ranges::v3::detail::composed_pipe<ranges::v3::view::view<ranges::v3::detail::pipeable_binder<std::_Bind<ranges::v3::view::split_fn(std::_Placeholder<1>, char)> > >, ranges::v3::view::all_fn> > >::pipe<Arg, Pipe>(Arg&&, Pipe) [with Arg = ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&; Pipe = ranges::v3::detail::pipeable_binder<ranges::v3::detail::composed_pipe<ranges::v3::view::view<ranges::v3::detail::pipeable_binder<std::_Bind<ranges::v3::view::split_fn(std::_Placeholder<1>, char)> > >, ranges::v3::view::all_fn> >]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/utility/functional.hpp:728:9:   required by substitution of 'template<class Arg, class Pipe, int _concept_requires_726, typename std::enable_if<((_concept_requires_726 == 43) || ((! ranges::v3::is_pipeable<T>()) && ranges::v3::is_pipeable<Pipe>())), int>::type <anonymous> > decltype (ranges::v3::pipeable_access::impl<Pipe>::pipe(static_cast<Arg&&>(arg), pipe)) ranges::v3::operator|(Arg&&, Pipe) [with Arg = ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&; Pipe = ranges::v3::detail::pipeable_binder<ranges::v3::detail::composed_pipe<ranges::v3::view::view<ranges::v3::detail::pipeable_binder<std::_Bind<ranges::v3::view::split_fn(std::_Placeholder<1>, char)> > >, ranges::v3::view::all_fn> >; int _concept_requires_726 = 42; typename std::enable_if<((_concept_requires_726 == 43) || ((! ranges::v3::is_pipeable<T>()) && ranges::v3::is_pipeable<Pipe>())), int>::type <anonymous> = 0]'
<source>:20:29:   required from here
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view/split.hpp:114:36: error: no match for call to '(const ranges::v3::invoke_fn) (ranges::v3::split_view<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>, ranges::v3::view::split_fn::element_pred<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char>&> >::cursor<true>::fun_ref_t&, ranges::v3::iterator_t<ranges::v3::delimit_view<ranges::v3::iterator_range<const char*, ranges::v3::unreachable>, char> >&, ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::adaptor_cursor<const char*, ranges::v3::adaptor_base> >)'
                     auto p = invoke(fun, first, ranges::next(first));
                          ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这是 view::c_str 的某种限制,还是 view::c_str 和 view::split 之间存在一些问题?

godbolt.org/g/bTK4Yp

wandbox.org/permlink/ZkDmSkBxPg80oebS

4

1 回答 1

5

此错误是由于split_view. 具体来说,在split_view::cursor::cursor()

cursor(fun_ref_t fun, iterator_t<Rng> first, sentinel_t<Rng> last)
    : cur_(first), last_(last), fun_(fun)
{
    // For skipping an initial zero-length match
    auto p = invoke(fun, first, ranges::next(first)); // <----
    zero_ = p.first && first == p.second;
}

标记的行fun使用来自底层范围的两个迭代器调用,尽管第 150-199 行的谓词函数实现接受来自底层范围的迭代器和哨兵

20180228 更新:

修复已签入,此错误不应再在 range-v3 master 上重现。

于 2018-02-27T22:15:57.213 回答