c++ - C++ 中的 string[length()] 可以吗?

标签 c++ string c++11

我同事的代码是这样的:

void copy(std::string const& s, char *d) {
  for(int i = 0; i <= s.size(); i++, d++)
    *d = s[i];
}

他的应用程序崩溃了,我认为这是因为访问 s 超出了范围,因为条件应该只达到 s.size() - 1

但我旁边的其他人说过去曾讨论过这是合法的。谁能帮我解决这个问题?

最佳答案

让我们撇开 *d 的可能性无效,因为这与问题似乎针对的内容无关:是否 std::string operator[]()在访问索引 std::string::size() 处的“元素”时具有明确定义的行为.

C++03标准对string::operator[]()的描述如下(21.3.4 "basic_string 元素访问"):

const_reference operator[](size_type pos) const;
reference operator[](size_type pos);

Returns: If pos < size(), returns data()[pos]. Otherwise, if pos == size(), the const version returns charT(). Otherwise, the behavior is undefined.

s在示例代码中是 const , 行为定义明确并且 s[s.size()]将返回一个空字符。但是,如果 s不是 const string ,行为将是未定义的。

C++11 补救了 const 的这种古怪行为在这种边缘情况下,版本的行为与非常量版本非常不同。 C++11 21.4.5“basic_string 元素访问”说:

const_reference operator[](size_type pos) const;
reference operator[](size_type pos);

Requires: pos <= size().

Returns: *(begin() + pos) if pos < size(), otherwise a reference to an object of type T with value charT(); the referenced value shall not be modified.

因此对于 C++11 编译器,行为是明确定义的,无论 string 是否存在。是const .

与问题无关,我觉得 C++11 说“引用的值不得修改”有点奇怪——我不清楚该条款是否仅适用于 pos == size() 的情况。 .我很确定有大量现有代码可以执行类似 s[i] = some_character; 的操作。其中 s是一个非常量 std:stringi < s.size() .现在是未定义的行为吗?我怀疑该条款仅适用于特殊情况 charT()对象。

另一个有趣的事情是,这两个标准似乎都没有要求为 s[s.size()] 返回对象的地址。以任何方式与为 s[s.size() - 1] 返回的对象的地址相关.换句话说,返回的似乎是 charT()引用不必与字符串数据的末尾连续。我怀疑这是为了给实现者一个选择,如果需要,只返回对该哨兵元素的单个静态拷贝的引用(这也可以解释 C++11 的“不得修改”限制,假设它仅适用于特殊的例)。

关于c++ - C++ 中的 string[length()] 可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10570534/

相关文章:

c++ - 如何检查一个字符串是否包含多个其他字符串?

c++ - 如何在不停止应用程序的情况下延迟功能

c++ - 从 'enable_shared_from_this' 派生一个类可以提高性能吗?

c++ - std::map<>::insert 使用不可复制对象和统一初始化

c++ - C 虚拟键盘输入有选择地工作

C++ 类重载运算符

c++ - 来自 boost::multi_array 的二维数组 - 无法编译

java - 如何在java中的map中允许重复的键?

python - 最好的方法是计算 python 中列表和字符串之间的匹配次数

c++ - std::unique_ptr 的自定义删除器如何工作?