为什么我不能从迭代器构造一个 std::span?



考虑一个大型内存容器。在这个简单的例子中,std::vector<int>:

std::vector v = { 0, 1, 2, 3, 4, 5 };

std::span允许我在内存上创建一个轻量级视图。现在我想简单地打印跨度:

template<typename T>
void print(std::span<T> span) {
std::cout << '[';
if (span.size())
std::copy(span.begin(), span.end() - 1, std::ostream_iterator<int>(std::cout, ", "));
std::cout << span.back() << "]n";
}
int main() {
std::vector v = { 0, 1, 2, 3, 4, 5 };
print(std::span{ v });
}

输出:

[0, 1, 2, 3, 4, 5]

现在我想制作子集(这就是std::span作为视图实际变得有用的地方(。我可以使用迭代器指定我的范围,并从std::span调用此构造函数(3(

template< class It, class End >
explicit(extent != std::dynamic_extent)
constexpr span( It first, End last );

但这不起作用:

print(std::span{ v.begin() + 2, v.end() }); //error E0289

C++没有构造函数实例与参数列表匹配。参数类型为:(std::_Vector_e迭代器<std::_Vector_val<td::conditional_t<true,std::_Simple_types,std::_Vec_iter_types<int,size_t,ptrdiff_t,int*,const int*,int&,const int&>>std:_Vector_i迭代器lt;std:::_Victor_val<std:conditional_t<size_t,ptrdiff_t,int*,const int*,int&,const int&>>gt>(


有可能使用构造函数(2(,该构造函数采用指针和大小:

print(std::span{ v.data() + 1, 3 }); //-> prints [1, 2, 3]

但这违背了迭代器的目的。

如何使用迭代器构造std::span?我是不是错过了什么


完整代码:

#include <iostream>
#include <vector>
#include <span>
#include <algorithm>
template<typename T>
void print(std::span<T> span) {
std::cout << '[';
if (span.size())
std::copy(span.begin(), span.end() - 1, std::ostream_iterator<int>(std::cout, ", "));
std::cout << span.back() << "]n";
}
int main() {
std::vector v = { 0, 1, 2, 3, 4, 5 };
print(std::span{ v.begin() + 2, v.end() });
}

在MSVC实现构造函数之前,我将使用此make_span函数:

template<typename It>
constexpr auto make_span(It begin, It end) {
return std::span<std::remove_pointer_t<It::pointer>>(&(*begin), std::distance(begin, end));
}

使用Visual Studio社区2019版本16.7.5。配置:x64,版本。C++语言标准=/std:C++最新

您可以使用迭代器构建span,它有这样一个构造函数(如P1394所添加的,您可以在[views.span]中看到(:

template< class It, class End >
explicit(extent != std::dynamic_extent)
constexpr span( It first, End last );

只是MSVC的标准库没有实现它。正如预期的那样,该程序在gcc上编译得很好。

相关内容

  • 没有找到相关文章

最新更新