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

Posted

技术标签:

【中文标题】修改 std::string::op[] 的结果是不是合法?【英文标题】:Is it legal to modify the result of std::string::op[]?修改 std::string::op[] 的结果是否合法? 【发布时间】:2011-10-14 10:05:05 【问题描述】:

考虑 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) 如果pos < size(),否则引用类型为T 且值为charT() 的对象;引用的值不得修改。

3    抛出:什么都没有。

4     复杂性: 恒定时间。

这意味着:

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

第二种情况看起来完全荒谬,但我认为这是措辞最强烈的含义。

我们是否可以修改从std::string::op[] 获得的内容? 这不是很模棱两可的措辞吗?

【问题讨论】:

看起来你可以......但不应该。 XD 等等,答案不是应该在 SHOULD 的定义中吗? @Klaim:这是关于“不应修改引用的值”的意思。 一个很好的问题,我的印象是c++11现在允许这样做,但很明显有一些理由怀疑它...... 实际上,我已经让其他一些人纯粹看语言,从英语(也不是我的第一个)角度来看,; 强制后一个条件适用于整个句子,基本上就目前而言,参考值不得修改 FWIW,假设我们理解我会写它的合理含义,“*(begin() + pos) 如果pos < size()。否则引用类型为charT 的对象,其值为charT();该对象应不可修改。” 【参考方案1】:

引号的意思是不能修改operator[]( size() )的返回值,即使值定义得很好。也就是说,即使通过非常量重载,也不能修改字符串中的 NUL 终止符。

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

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

【讨论】:

这是我提到的第一种可能性(是的,我知道它可以浓缩为pos == size()),但你能确定这就是它的意思吗? 如果 operator[] 即使在非常量重载中也不允许您修改内容,那将是 C++03 语义中的(无意义的)中断,它会列在标准的C 兼容性 附录中。我不是以英语为母语的人,但常识决定了这种解释。 是的,它实际上意味着:如果 pos==size() 则它返回对不应修改的 charT() 的引用。我认为逗号和分号是交换的,因为在英文中,; 的优先级高于','。 @TomalakGeret'kal 我正在提供我的解释,以及在附录 C(特别是 C.2.11)中出现的语义中断的附加位,以及语义中的其他两个变化.在该部分中没有提及可以用作暗示 C++03 中的语义得到维护,并且 C++03 对通过operator[] 更改值没有任何限制。至于问题我确定吗?,是的,我确定。 “我不是以英语为母语的人”——没关系,有时我认为标准的作者也不是。毫无疑问,有些提供文本的人确实不是,所以我绝对同意,在标准其余部分的上下文中进行解释比严格的英语字母语法阅读更重要。【参考方案2】:

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

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

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

【讨论】:

以上是关于修改 std::string::op[] 的结果是不是合法?的主要内容,如果未能解决你的问题,请参考以下文章

修改蛋糕关联结果数组

修改代码运行的还是旧代码

如何按修改日期对 CloudKit 结果进行排序?

oracle数据库,查询到的结果怎样修改??

如何修改SOLR tf idf相似度?

SARscape中的PS处理——修改第一次反演后子区域的结果