c++ - 为什么我不能从迭代器构造 std::span ?

标签 c++ iterator c++20 std-span

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

std::vector v = { 0, 1, 2, 3, 4, 5 };
std::span 允许我创建一个轻量级的内存 View 。现在我想简单地打印跨度:
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 实际上作为 View 变得有用的地方)。我可以使用迭代器来指定我的范围并调用 this constructor(3)来自 std::span
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++ no instance of constructor matches the argument list argument types are: (std::_Vector_iterator<std::_Vector_val<std::conditional_t<true, std::_Simple_types, std::_Vec_iter_types<int, size_t, ptrdiff_t, int *, const int *, int &, const int &>>>>, std::_Vector_iterator<std::_Vector_val<std::conditional_t<true, std::_Simple_types, std::_Vec_iter_types<int, size_t, ptrdiff_t, int *, const int *, int &, const int &>>>>)



有可能使用带有指针和大小的构造函数(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 Community 2019 版本 16.7.5。配置:x64,发布。 C++ 语言标准 =/std:c++latest

最佳答案

您可以构建一个 span使用迭代器,它有 such a constructor (由 P1394 添加,您可以在 [views.span] 中看到):

template< class It, class End >
explicit(extent != std::dynamic_extent)
constexpr span( It first, End last );
只是 MSVC 的标准库没有实现。正如预期的那样,该程序在 gcc 上编译得很好。

关于c++ - 为什么我不能从迭代器构造 std::span ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64186919/

相关文章:

c++ - Ruby block ,C++ 中的 java 闭包

c++ - 在 C++20 中,立即函数的默认参数在哪个上下文中被替换(在源位置示例中)?

c++ - c++20 [[no_unique_address]] 中的新特性是什么?

C++ 飞船运算符多级比较?

c++ - 为什么继承不会增加大小,但成员会增加?

c++ - 如何从元组 C++ 中过滤重复类型

JavaScript 迭代器类

c++ - 内存 sanitizer

c++ - 从 R 调用 C++

c++ - 如何使用 C++ Boost 的 regex_iterator()