Constant LegacyBidirectionalIterator与指向const value_type的迭代器的区别
问题背景
查询std::set的成员类型iterator时,预期它是指向value_type const的LegacyBidirectionalIterator,但cppreference给出的定义如下:
| 成员类型 | 定义 |
|---|---|
| ... | ... |
iterator | Constant LegacyBidirectionalIterator to value_type |
const_iterator | LegacyBidirectionalIterator to const value_type |
| ... | ... |
实际中这两种类型可能是同一类型,但二者在定义上有何区别?
另外,LegacyForwardIterator(LegacyBidirectionalIterator的基类)区分了普通LegacyForwardIterator和mutable LegacyForwardIterator,前者不可修改(即const)。但std::forward_list的iterator定义仅为:
| 成员类型 | 定义 |
|---|---|
iterator | LegacyForwardIterator to value_type |
这是否说明cppreference存在疏漏或错误?Constant *LegacyBidirectionalIterator* to value_type与*LegacyBidirectionalIterator* to const value_type的区别究竟是什么?
核心区别解析
这两种表述本质上是从不同角度描述同一个不可修改的迭代器特性,不存在cppreference的疏漏:
Constant LegacyBidirectionalIterator to value_type:这里的Constant修饰迭代器本身的特性——它属于不可修改元素的迭代器范畴。也就是说,无论value_type本身是否为const,通过这个迭代器都无法修改指向的对象,这是迭代器自身的属性。LegacyBidirectionalIterator to const value_type:这个表述从迭代器指向的对象类型出发,明确迭代器指向的是const value_type,因此自然无法通过它修改对象。
对于std::set而言,由于内部元素依赖有序性保证唯一性,不允许通过迭代器修改元素,所以它的iterator和const_iterator都具备不可修改元素的特性,很多实现里甚至会让这两个类型完全等价。
关于std::forward_list的迭代器
std::forward_list的iterator是可修改的迭代器(mutable LegacyForwardIterator),cppreference仅标注LegacyForwardIterator to value_type是因为:默认情况下,未标注Constant的迭代器即为可修改类型,这和LegacyForwardIterator的分类规则一致——只有明确标注Constant的才是不可修改迭代器,普通迭代器默认具备修改能力。
综上,cppreference的表述是严谨的:
- 对于不允许修改元素的容器(如
std::set、std::map的键迭代器),其普通iterator会标注Constant,明确不可修改的特性; - 对于允许修改元素的容器(如
std::forward_list、std::vector),普通iterator无需额外标注,默认代表可修改迭代器。
内容的提问来源于stack exchange,提问作者bitmask

