我可以取消引用 std::string.end() 吗?

muk*_*nda 9 c++ string std language-lawyer

我相信对此的常见反应是“不”,end()因为容器的迭代器表示“过去结束”地址,这是取消引用的未定义行为。我在标准中找不到一个明确的声明来免除字符串的约束,即使字符串比其他容器有特殊情况。

C++11 标准声明您可以读取超过字符串末尾的一个索引。string[size()]引用空终止符的只读值。

24.3.2.5 basic_string 元素访问 [string.access]

const_reference operator[](size_type pos) const;

reference operator[](size_type pos);

(1)要求: pos <= size() .

(2)回报: *(begin() + pos) if pos < size()。否则,返回对类型charT为 value的对象的引用 charT(),其中将对象修改为除charT()导致未定义行为之外的任何值。

front()被定义为等效于return operator[](0)which 等效return operator[](size())于一个空字符串。

end() - begin()被明确定义为字符串长度的差异,因此end()必须指向的索引size()才能定义该算术。

在上面的标准摘录中,它说明这operator[](pos)等效于*(begin() + pos)if pos < size()。它并不是说您可以取消引用begin() + size(),但您认为假设这应该被明确定义是否合理?或者更好的是,您是否知道一些证明可以将字符串迭代器从约束中排除?

另外,能否证明*(begin() + i)for anyi等价于operator[](i)?

cig*_*ien 5

string.end()的定义来看

返回: 一个迭代器,它是最后的值。

并从过去结束的定义:

......这样的值被称为过去的值。定义了表达式 *i 的迭代器 i 的值称为可解引用。库从不假设越过末尾的值是可取消引用的。...

重点是我的,我想任何例外std::string都会在第一个链接中提到。因为它不是,所以取消引用std::string.end()是由省略定义的。