我尝试了一个小例子来熟悉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>
span
目前需要进行一些调整
在一些(非工业)软件中将两个库一起使用。什么
我应该改变这些工作吗? (如果这是一个好主意)range-v3
合作?“是从外墙继承,
适配器或目前只告诉编译器这些概念要求的唯一方法是什么?答案 0 :(得分:9)
范围-v3中的View
概念(以及范围TS,就此而言)要求类型R
同时满足Range
概念 - begin(r)
和end(r)
分隔迭代器范围 - Semiregular
概念 - R
必须是复制/移动可构造复制/移动可分配,并且默认可构造。 Range
(begin
和end
返回)的迭代器和标记类型也必须为Semiregular
(以及其他要求)。
span
系列并不满足View
概念,因为span
在某些情况下不是默认可构造的,并且它们的迭代器在任何情况下都不是默认构造的。因为即使标准C ++需要前向迭代器的默认构造,当前的span
迭代器既不符合Ranges TS,range-v3,也不符合标准C ++。
尽管如此,为满足所有这些要求系列所需的变更are minimal and straight-forward。
range-v3现在包含span
的实现,可以对View
/ Range
概念进行正确建模。
gsl::span
现在有默认的可构造迭代器。因此,跨度现在可用于范围-v3。具有动态范围的跨度(例如gsl::span<int>
)模拟Range
&amp; View
概念,仅涵盖 static 范围(例如,gsl::span<int, 42>
)模型Range
,因为它们不符合View
的要求用于默认构造。