为什么std::vector<int>::iterator不是一个连续迭代器?

4
根据标准,正如这里所引用的,vector<T>::iterator 应该是连续的(对于除了bool之外的T),但在所有三个主要的实现中,它都不是,为什么呢?
#include <iterator>
#include <vector>

using InputIterator = std::vector<int>::iterator;
static_assert(std::is_same_v<typename std::iterator_traits<InputIterator>::iterator_category, std::random_access_iterator_tag>);
static_assert(std::is_same_v<typename std::iterator_traits<InputIterator>::iterator_category, std::contiguous_iterator_tag>);

第一个static_assert成功,但是最新的MSVC、GCC和clang都失败了。

https://godbolt.org/z/oG1x1xdda


阅读关于std::iterator_traits的内容,它指出iterator_category用于传统迭代器类别,而iterator_concept用于现代迭代器概念。建议尝试检查iterator_concept - undefined
1
有很多代码依赖于iterator_categoryrandom_access_iterator_tag,因此它还没有被更改为contiguous_iterator_tag。请注意,迭代器类别与contiguous_­iterator概念不同。 - undefined
@molbdnilo: 我明白了!我现在才意识到我正在检查 is_same_v,所以它不可能同时为真,但我最初预期它既是随机访问迭代器又是连续迭代器,这是不可能的 - 至少在这种方式下测试是不可能的。 - undefined
1个回答

8

std::vector<int>::iterator 是指满足 std::contiguous_iterator 概念和 连续迭代器 要求的连续迭代器。

std::iterator_traits 不会测试某个对象是否满足 连续迭代器 的要求,因为这些是语义要求。 甚至指针的 iterator_category 也没有 contiguous_iterator_tag,如 [iterator.traits] p5 中所述。任何类型只有通过特化 std::iterator_traits 才能具有这个标签。

你应该使用相关的概念来测试std::vector<int>::iterator是否是随机访问迭代器,甚至是连续迭代器:
#include <iterator>
#include <vector>

static_assert(std::random_access_iterator<std::vector<int>::iterator>); // OK
static_assert(std::contiguous_iterator<std::vector<int>::iterator>);    // OK

请参见编译器资源浏览器上的实时示例

请注意,此测试可能会产生误报。如[iterator.concept.contiguous] p2中所述,std::contiguous_iterator具有额外的语义约束,即使迭代器不是连续迭代器的模型,该概念也可能满足

还请注意,std::iterator_traits也可能具有iterator_concept的别名成员,但仅适用于指针或用户为其类型专门化了std::iterator_traits。它的存在不被保证,您应该直接使用概念。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接