将 gsl::span 与 range-v3 一起使用
Using gsl::span with range-v3
我尝试了一个小例子来习惯 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()
迭代器(同类型)。
- 如果它们一起工作是可组合的或者是
两者有什么不兼容的原因吗?
- 我认为这是一个来自强烈 "concept" 用法的问题
在范围-v3 中。如果有其他类型的问题,它会自动解决吗
语言支持概念特征?
- 我假设
span
目前需要一些适应,如果我愿意的话
在某些(非工业)软件中同时使用这两个库。什么
我应该改变以使它们一起工作吗? (如果这是个好主意的话)
- 这最终也让我想到了“什么有 class
fullfill to work with
range-v3
?" 是从门面继承的,
适配器或其他目前告诉编译器这些概念要求的唯一方法?
range-v3 中的 View
概念(以及范围 TS,就此而言)需要类型 R
来满足 Range
概念 -- begin(r)
和 end(r)
界定迭代器范围——以及 Semiregular
概念——R
必须是 copy/move 可构造的 copy/move 可分配的,并且默认可构造的。 Range
的迭代器和标记类型(begin
和 end
return)也必须是 Semiregular
(除其他要求外)。
span
系列不满足 View
概念,因为 span
在某些情况下不是默认可构造的,并且它们的迭代器在任何情况下都不是默认可构造的。因为即使是标准 C++ 也需要 Forward 迭代器的默认构造,当前 span
迭代器既不符合 Ranges TS、range-v3 也不符合标准 C++。
也就是说,满足所有这些要求系列所必需的更改 are minimal and straight-forward。
20161207更新:
range-v3 现在包含 span
的实现,它正确地模拟了 View
/Range
概念。
20170128更新:
gsl::span
现在有默认的可构造迭代器。因此,跨度现在可用于 range-v3。具有动态范围的跨度(例如 gsl::span<int>
)模拟 Range
和 View
概念,具有 静态 范围的跨度(例如 gsl::span<int, 42>
) 仅模型 Range
,因为它们不符合 View
的默认构造要求。
我尝试了一个小例子来习惯 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()
迭代器(同类型)。
- 如果它们一起工作是可组合的或者是 两者有什么不兼容的原因吗?
- 我认为这是一个来自强烈 "concept" 用法的问题 在范围-v3 中。如果有其他类型的问题,它会自动解决吗 语言支持概念特征?
- 我假设
span
目前需要一些适应,如果我愿意的话 在某些(非工业)软件中同时使用这两个库。什么 我应该改变以使它们一起工作吗? (如果这是个好主意的话) - 这最终也让我想到了“什么有 class
fullfill to work with
range-v3
?" 是从门面继承的, 适配器或其他目前告诉编译器这些概念要求的唯一方法?
range-v3 中的 View
概念(以及范围 TS,就此而言)需要类型 R
来满足 Range
概念 -- begin(r)
和 end(r)
界定迭代器范围——以及 Semiregular
概念——R
必须是 copy/move 可构造的 copy/move 可分配的,并且默认可构造的。 Range
的迭代器和标记类型(begin
和 end
return)也必须是 Semiregular
(除其他要求外)。
span
系列不满足 View
概念,因为 span
在某些情况下不是默认可构造的,并且它们的迭代器在任何情况下都不是默认可构造的。因为即使是标准 C++ 也需要 Forward 迭代器的默认构造,当前 span
迭代器既不符合 Ranges TS、range-v3 也不符合标准 C++。
也就是说,满足所有这些要求系列所必需的更改 are minimal and straight-forward。
20161207更新:
range-v3 现在包含 span
的实现,它正确地模拟了 View
/Range
概念。
20170128更新:
gsl::span
现在有默认的可构造迭代器。因此,跨度现在可用于 range-v3。具有动态范围的跨度(例如 gsl::span<int>
)模拟 Range
和 View
概念,具有 静态 范围的跨度(例如 gsl::span<int, 42>
) 仅模型 Range
,因为它们不符合 View
的默认构造要求。