使用gsl :: span和range-v3

时间:2016-03-26 10:30:06

标签: c++ range-v3 guideline-support-library

我尝试了一个小例子来熟悉GSL和range-v3库,我想知道它们如何协同工作。我有这个玩具示例

#include <iostream>
#include <range/v3/all.hpp>

using namespace std;
using namespace ranges;

void example_vector(vector<int> const& v)
{
  ranges::for_each(view::tail(v), [](int x){
    cout << x << ' ';
  });
  cout << '\n';
}

int main()
{
   auto seq = vector<int> { 2,2,2,0,0,2,1,2 };
   example_vector(seq);
}

哪个有效。但是,如果我尝试使用gsl::span<int>作为范围,则会导致错误消息。编译器告诉我span没有满足视图概念。

#include <gsl.h>

// ...

void example_span(gsl::span<const int> v)
{
  ranges::for_each(view::tail(v), [](int x){
    cout << x << ' ';
  });
  cout << '\n';
}

编译器消息:

note: candidate template ignored: disabled by 'enable_if'
      [with Rng = gsl::span<const int, -1> &, Rest = <>, _concept_requires_123 = 42]
                    CONCEPT_REQUIRES_(ViewConcept<Rng, Rest...>())>

但在我的理解中,它应该是因为span 特定视图,甚至还有begin()end()迭代器(相同类型)。< / p>

  • 如果他们一起工作是可以组合的,那会不会很酷 有什么理由让两者不相容吗?
  • 我认为这是一个来自强大的“概念”用法的问题 在范围-v3中。它是否会在其他类型的情况下自动解决 概念功能是否受语言支持?
  • 如果我愿意,我认为span目前需要进行一些调整 在一些(非工业)软件中将两个库一起使用。什么 我应该改变这些工作吗? (如果这是一个好主意)
  • 这也让我最终得到了“有什么课程的问题” fullfill与range-v3合作?“是从外墙继承, 适配器或目前只告诉编译器这些概念要求的唯一方法是什么?

1 个答案:

答案 0 :(得分:9)

范围-v3中的View概念(以及范围TS,就此而言)要求类型R同时满足Range概念 - begin(r)end(r)分隔迭代器范围 - Semiregular概念 - R必须是复制/移动可构造复制/移动可分配,并且默认可构造。 Rangebeginend返回)的迭代器和标记类型也必须为Semiregular(以及其他要求)。

span系列并不满足View概念,因为span在某些情况下不是默认可构造的,并且它们的迭代器在任何情况下都不是默认构造的。因为即使标准C ++需要前向迭代器的默认构造,当前的span迭代器既不符合Ranges TS,range-v3,也不符合标准C ++。

尽管如此,为满足所有这些要求系列所需的变更are minimal and straight-forward

20161207更新:

range-v3现在包含span的实现,可以对View / Range概念进行正确建模。

20170128更新:

gsl::span现在有默认的可构造迭代器。因此,跨度现在可用于范围-v3。具有动态范围的跨度(例如gsl::span<int>)模拟Range&amp; View概念,仅涵盖 static 范围(例如,gsl::span<int, 42>)模型Range,因为它们不符合View的要求用于默认构造。