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
概念,即 gcc
和 clang
都失败了,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 在添加适当的概念时添加了这样一个标签(和其他东西)。
可以通过范围构造函数和一对显式迭代器从 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
概念,即 gcc
和 clang
都失败了,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 在添加适当的概念时添加了这样一个标签(和其他东西)。