Boost 的 small_vector 的迭代器类型不应该满足 std::contiguous_iterator 概念吗?

Shouldn't the iterator types of Boost's small_vector satisfy the std::contiguous_iterator concept?

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

#include <span>
#include <vector>

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

但是当对来自 Boost 的容器库的 small_vector 做同样的事情时,它也应该是连续的,我 运行 遇到了问题 (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 概念,即 gccclang 都失败了,libc++libstdcxx (godbolt):

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

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

std::contiguous_iterator 在 C++20 中有 specific requirements,它不是任何 pre-C++20 接口的一部分。由于这些接口在 C++20 之前不存在(特别是 contiguous_iterator_tag),因此 small_vector<T>::iterator.

无法使用它们

当然可以加上这样的接口,前提是有C++20的特性。但是在 C++20 出现之前编写的代码如果不进行更新就无法成为 contiguous_iterator。虽然有 C++17“ContiguousIterator”要求,但它没有标记或其他方法来 检测 迭代器是否连续。 C++20 在添加适当的概念时添加了这样一个标签(和其他东西)。