修改std :: string :: op []的结果是否合法?

时间:2011-10-14 10:05:06

标签: c++ string std

从C ++ 11开始考虑以下内容:

  

[C++11: 21.4.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(),否则引用T类型的对象,其值为{{1} }};参考值不得修改。

     

3 投掷:没什么。

     

4 复杂性:恒定时间。

这意味着:

  • charT()案例中的引用值不得修改,或
  • 任何的情况下,pos == size()返回的引用值不会被修改,即使对于非op[]重载也是如此。

第二种情况似乎完全荒谬,但我认为这是措辞最强烈暗示的内容。

我们可以修改我们从const得到的内容吗?这是不是很模糊的措辞?

2 个答案:

答案 0 :(得分:12)

引用意味着即使值已明确定义,也无法修改operator[]( size() )的返回值。也就是说,即使通过非const重载,也不得修改字符串中的NUL终止符。

这基本上是您的第一个选择:即pos >= size(),但由于要求pos <= size(),该条件的唯一可能值为pos == size()

该子句的实际英文描述可能含糊不清(至少对我而言),但附录C,特别是C.2.11处理字符串库中语义的变化,并没有提及这种变化 - 这将打破用户代码。在C ++ 03中,“引用值不应被修改”位不存在且没有歧义。 C.2.11中没有提及不是规范性的,但可以作为暗示,当他们编写标准时,无意改变这种特殊行为。

答案 1 :(得分:4)

在n3690(C ++ 14草案)中,措辞已改为:

  

如果*(begin() + pos),则返回 pos < size()。否则,返回对值为charT的{​​{1}}类型的对象的引用,其中修改对象会导致未定义的行为。

我相信这解决了英语歧义,并明确了原始的,模棱两可的C ++ 11段落的意图。