微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

可以通过范围构造函数和显式的迭代器对从 std::span(作为连续容器的原型)构造 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

但是,当对 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 都失败了,{{1} } 和 libc++ (godbolt):

libstdcxx

static_assert( std::contiguous_iterator<boost::container::small_vector<int,10>::iterator>); 的存储可能就地或在堆上,但始终是连续的。那么这里的问题是什么?

解决方法

std::contiguous_iterator 在 C++20 中有 specific requirements,它不是任何 C++20 之前的接口的一部分。由于这些接口在 C++20 之前不存在(尤其是 contiguous_iterator_tag),因此 small_vector<T>::iterator 无法使用它们。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。