为什么std::span
只有begin
和end
的方法,而没有它们的常量迭代器对应物cbegin
和cend
?(标准(
我还注意到,我能找到的跨度提案确实对cbegin
和cend
有一个定义:P0122R7。为什么它被删除了?
作为更新,这些由P2278R4添加回来。下面指出的LWG问题仍然是一个问题,x.cbegin()
和std::cbegin(x)
会做不同的事情,但现在x.cbegin()
和std::ranges::cbegin(x)
做同样的事情。
由于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所建议的那样(,但这可以说是令人困惑的,因此解决方案决定是简单地删除所有常量成员和别名。
无论如何,如果您希望容器本身不可变(这不是span
的问题(,std::cbegin(s)
始终有效。
†从技术上讲,实现是定义的,不是必需的int const*
,但这是一个有用的解释性虚构。