其他分享
首页 > 其他分享> > c – view :: c_str是否存在view :: split的问题?

c – view :: c_str是否存在view :: split的问题?

作者:互联网

特定

auto cstr = "quick brown fox";

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

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

如果source是string_view,那就是okey.

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

输出:[wandbox]

[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

解决方法:

此错误是由于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,尽管the predicate function implementations on lines 150-199接受来自基础范围的迭代器和标记.

20180228更新:

签入此修复程序,此bug不再在range-v3 master上重现.

标签:c,lazy-evaluation,range-v3
来源: https://codeday.me/bug/20190828/1748305.html