首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以将“range-v3”包含与c++“range”包含混合?

是否可以将“range-v3”包含与c++“range”包含混合?
EN

Stack Overflow用户
提问于 2021-10-04 19:29:04
回答 1查看 248关注 0票数 3

我有权使用GCC 10,并用-std=c++20编译,需要诸如generate cache1concat等视图,这些视图可能要到C++23才会发布。

我在下面写了一个简单的程序,使用range-v3输出'1 2 2 3 3‘。我尝试将range-v3视图和ranges包含的视图混合在一起,但没有成功。“ranges”库似乎希望视图继承自view_interface,所以我创建了一个wrap_view_t来帮助实现这一点(未显示)。要查看工作范围-v3代码,请注释该行:

//#define MIX_RANGES_WITH_RANGE_V3

代码如下:

代码语言:javascript
复制
#include <iostream>

#define MIX_RANGES_WITH_RANGE_V3

#ifdef  MIX_RANGES_WITH_RANGE_V3
#include <ranges>
namespace test { using namespace std::ranges; }
#else
#include <range/v3/view/all.hpp>
#include <range/v3/view/interface.hpp>
#include <range/v3/view/join.hpp>
#include <range/v3/view/take_while.hpp>
#include <range/v3/view/transform.hpp>
namespace test { using namespace ranges; }
#endif
#include <range/v3/view/generate.hpp>
#include <range/v3/view/cache1.hpp>


auto my_view()
{
  auto gen{ ranges::views::generate( [ n = 0 ]() mutable
  {
    return std::vector< int >( ++n, n );
  } )
    | ranges::views::cache1
  };

  return std::move( gen )
    | test::views::take_while( []( auto const & value ) { return value.size() < 4; } )
    | test::views::transform( []( auto const & value )
    { return test::views::all( value ); } );

}

int main()
{
  for( auto const value : my_view() | test::views::join )
  {
    std::cout <<value <<" ";
  }
  std::cout <<std::endl;

  return 0;
}

和编译器错误

代码语言:javascript
复制
test_rng/test_rng_simpler.C: In function ‘auto my_view()’:
test_rng/test_rng_simpler.C:28:3: error: no match for ‘operator|’ (operand types are ‘std::remove_reference<ranges::cache1_view<ranges::generate_view<my_view()::<lambda()> > >&>::type’ {aka ‘ranges::cache1_view<ranges::generate_view<my_view()::<lambda()> > >’} and ‘std::ranges::views::__adaptor::_RangeAdaptorClosure<std::ranges::views::__adaptor::_RangeAdaptor<_Callable>::operator()<{my_view()::<lambda(const auto:16&)>}>::<lambda(_Range&&)> >’)
   27 |  return std::move( gen )
      |         ~~~~~~~~~~~~~~~~
      |                  |
      |                  std::remove_reference<ranges::cache1_view<ranges::generate_view<my_view()::<lambda()> > >&>::type {aka ranges::cache1_view<ranges::generate_view<my_view()::<lambda()> > >}
   28 |   | test::views::take_while( []( auto const & value ) { return value.size() < 4; } )
      |   ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                            |
      |                            std::ranges::views::__adaptor::_RangeAdaptorClosure<std::ranges::views::__adaptor::_RangeAdaptor<_Callable>::operator()<{my_view()::<lambda(const auto:16&)>}>::<lambda(_Range&&)> >
In file included from test_rng/test_rng_simpler.C:6:
/opt/rh/devtoolset-10/root/usr/include/c++/10/ranges:1180:4: note: candidate: ‘template<class _Tp> constexpr auto std::ranges::views::__adaptor::operator|(const std::ranges::views::__adaptor::_RangeAdaptorClosure<_Callable>&, const std::ranges::views::__adaptor::_RangeAdaptorClosure<std::ranges::views::__adaptor::_RangeAdaptor<_Callable>::operator()<{my_view()::<lambda(const auto:16&)>}>::<lambda(_Range&&)> >&)’
 1180 |    operator|(const _RangeAdaptorClosure<_Tp>& __x,
      |    ^~~~~~~~
/opt/rh/devtoolset-10/root/usr/include/c++/10/ranges:1180:4: note:   template argument deduction/substitution failed:
test_rng/test_rng_simpler.C:28:84: note:   ‘std::remove_reference<ranges::cache1_view<ranges::generate_view<my_view()::<lambda()> > >&>::type’ {aka ‘ranges::cache1_view<ranges::generate_view<my_view()::<lambda()> > >’} is not derived from ‘const std::ranges::views::__adaptor::_RangeAdaptorClosure<_Callable>’
   28 |   | test::views::take_while( []( auto const & value ) { return value.size() < 4; } )
      |                                                                                    ^
In file included from test_rng/test_rng_simpler.C:6:
/opt/rh/devtoolset-10/root/usr/include/c++/10/ranges:1175:4: note: candidate: ‘constexpr auto std::ranges::views::__adaptor::operator|(_Range&&, const std::ranges::views::__adaptor::_RangeAdaptorClosure<_Callable>&) [with _Range = ranges::cache1_view<ranges::generate_view<my_view()::<lambda()> > >; _Callable = std::ranges::views::__adaptor::_RangeAdaptor<_Callable>::operator()<{my_view()::<lambda(const auto:16&)>}>::<lambda(_Range&&)>]’
 1175 |    operator|(_Range&& __r, const _RangeAdaptorClosure& __o)
      |    ^~~~~~~~
/opt/rh/devtoolset-10/root/usr/include/c++/10/ranges:1175:4: note: constraints not satisfied
test_rng/test_rng_simpler.C: In instantiation of ‘constexpr auto std::ranges::views::__adaptor::operator|(_Range&&, const std::ranges::views::__adaptor::_RangeAdaptorClosure<_Callable>&) [with _Range = ranges::cache1_view<ranges::generate_view<my_view()::<lambda()> > >; _Callable = std::ranges::views::__adaptor::_RangeAdaptor<_Callable>::operator()<{my_view()::<lambda(const auto:16&)>}>::<lambda(_Range&&)>]’:
test_rng/test_rng_simpler.C:28:84:   required from here
/opt/rh/devtoolset-10/root/usr/include/c++/10/ranges:78:13:   required for the satisfaction of ‘viewable_range<_Range>’ [with _Range = ranges::cache1_view<ranges::generate_view<my_view::._anon_131> >]
/opt/rh/devtoolset-10/root/usr/include/c++/10/ranges:79:31: note: no operand of the disjunction is satisfied
   79 |       && (borrowed_range<_Tp> || view<remove_cvref_t<_Tp>>);
      |          ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

也许我应该坚持'range-v3‘,直到我需要的所有视图在’range‘中都可用,包括?

EN

回答 1

Stack Overflow用户

发布于 2021-10-05 02:11:00

由于range-v3中的适配器不继承ranges::view_interface,这使得它们不是标准中的view。为了避免悬空的危险,该标准禁止将不对borrowed_rangeview (在您的示例中为gen)建模的range传递到管道中。

您需要做的是使用一个临时变量来接受generate,使其成为一个左值range,这样就可以满足borrowed_range并使用标准管道操作:

代码语言:javascript
复制
#include <iostream>
#include <ranges>
#include <range/v3/view/generate.hpp>
#include <range/v3/view/cache1.hpp>

int main() {
  auto gen = ranges::views::generate([n = 0]() mutable {
      return std::vector<int>(++n, n);
    }) | ranges::views::cache1;

  for (auto const value : gen
    | std::views::take_while([](auto const& value) { return value.size() < 4; })
    | std::views::transform([](auto const& value) { return std::views::all(value); })
    | std::views::join) {
      std::cout <<value <<" ";
  }
}

Demo.

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69441401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档