2

std::span可以通过范围构造函数和一对显式迭代器从 a构造 a std::vector(作为连续容器的原型):

#include <span>
#include <vector>

std::vector<int> owning;
std::span<int> view1{owning.begin(), owning.end()}; // works
std::span<int> view2{owning}; // works

但是,当使用small_vectorBoost 的容器库中的一个也应该是连续的时,我遇到了问题(godbolt):

#include <span>
#include <boost/container/small_vector.hpp>

boost::container::small_vector<int, 10> owning;
std::span<int> view1{owning.begin(), owning.end()}; // Error
std::span<int> view2{owning}; // Error (works with clang + libc++ though)

问题似乎是 的迭代器boost::small_vector不满足这个std::contiguous_iterator概念,即这两者都失败了gccand clang, libc++and libstdcxx( godbolt ):

static_assert(
    std::contiguous_iterator<boost::container::small_vector<int, 10>::iterator>);

的存储small_vector可能就地或堆上,但始终是连续的。那么这里有什么问题呢?

4

1 回答 1

1

std::contiguous_iterator在 C++20 中具有特定要求,这些要求不属于任何 C++20 之前的接口。由于这些接口在 C++20 之前不存在(尤其是contiguous_iterator_tag),因此它们不能被small_vector<T>::iterator.

当然可以添加这样一个接口,条件是 C++20 特性的存在。但是在 C++20 出现之前编写的代码根本无法在contiguous_iterator没有工作的情况下对其进行更新。虽然有 C++17“ContiguousIterator”要求,但它没有标记或其他方法来检测迭代器是否连续。C++20 在添加适当的概念时添加了这样的标签(和其他东西)。

于 2021-07-15T13:42:38.377 回答