【发布时间】:2020-10-26 16:11:18
【问题描述】:
为什么std::span 只有begin 和end 方法,而没有它们的常量迭代器对应物cbegin 和cend? (standard)
我还注意到,我能找到的跨度提案确实有cbegin 和cend 的定义:P0122R7。为什么被删除了?
【问题讨论】:
标签: c++ iterator c++20 std-span
为什么std::span 只有begin 和end 方法,而没有它们的常量迭代器对应物cbegin 和cend? (standard)
我还注意到,我能找到的跨度提案确实有cbegin 和cend 的定义:P0122R7。为什么被删除了?
【问题讨论】:
标签: c++ iterator c++20 std-span
由于LWG3320,此内容已被删除。
问题是x.cbegin() 应该和std::begin(std::as_const(x)) 做同样的事情,这就是std::cbegin(x) 的定义。
但std::span 的情况并非如此,因为它实际上并不拥有它的元素,因此只有浅常量。给定span<int> s;,s.cbegin() 会给你一个int const*†,而std::cbegin(s) 给你一个int*。这是非常不一致的。本来可以保留 s.cbegin() 而让它只返回 begin()(由 PL 247 提议),但这可以说是令人困惑的,因此决议决定是简单地删除所有 const 成员和别名。
无论如何,如果您希望容器本身是不可变的,std::cbegin(s) 总是可以工作的(这对span 来说不是问题)。
†从技术上讲,实现已定义,不是必需的 int const*,但这是用于解释目的的有用虚构。
【讨论】:
cbegin 等会返回一个常量迭代器,我个人可能更喜欢,但我同意它会带来一些混乱。那么现在在元素上获取 const 迭代器的最佳方法是什么?
span<T> 本身转换为span<T const>。