c++ - 这是违法的吧?

标签 c++ string iterator

对于个人项目,我一直在实现自己的 libstdc++。一点一点地,我取得了一些不错的进步。通常,我会将 http://www.cplusplus.com/reference/ 中的示例用于一些基本测试用例,以确保我具有按预期工作的明显功能。

今天我遇到了 std::basic_string::replace 的问题,特别是使用从网站 (http://www.cplusplus.com/reference/string/string/replace/) 逐字复制的示例的基于迭代器的版本(我添加了指出有问题的行的评论):

// replacing in a string
#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string base="this is a test string.";
  string str2="n example";
  string str3="sample phrase";
  string str4="useful.";

  // function versions used in the same order as described above:

  // Using positions:                 0123456789*123456789*12345
  string str=base;                // "this is a test string."
  str.replace(9,5,str2);          // "this is an example string."
  str.replace(19,6,str3,7,6);     // "this is an example phrase."
  str.replace(8,10,"just all",6); // "this is just a phrase."
  str.replace(8,6,"a short");     // "this is a short phrase."
  str.replace(22,1,3,'!');        // "this is a short phrase!!!"

  // Using iterators:                      0123456789*123456789*
  string::iterator it = str.begin();   //  ^
  str.replace(it,str.end()-3,str3);    // "sample phrase!!!"

  // *** this next line and most that follow are illegal right? ***

  str.replace(it,it+6,"replace it",7); // "replace phrase!!!"
  it+=8;                               //          ^
  str.replace(it,it+6,"is cool");      // "replace is cool!!!"
  str.replace(it+4,str.end()-4,4,'o'); // "replace is cooool!!!"
  it+=3;                               //             ^
  str.replace(it,str.end(),str4.begin(),str4.end());
                                       // "replace is useful."
  cout << str << endl;
  return 0;
}

在我的版本中,替换是根据我创建的临时字符串实现的,然后用 *this 交换。这显然会使任何迭代器无效。那么我是否正确认为该示例无效?因为它存储迭代器,进行替换然后再次使用迭代器?

我的标准拷贝 (ISO 14882:2003 - 21.3p5) 说:

References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated by the following uses of that basic_string object:

- As an argument to non-member functions swap() (21.3.7.8), 
  operator>>() (21.3.7.9), and getline() (21.3.7.9).
- As an argument to basic_string::swap().
- Calling data() and c_str() member functions.
- Calling non-const member functions, except operator[](), at(),
  begin(), rbegin(),
  end(), and rend().
- Subsequent to any of the above uses except the forms of insert() and
  erase() which return iterators,
  the first call to non-const member functions operator[](), at(), begin(),
  rbegin(), end(), or rend().

关于非常量成员函数的条目似乎涵盖了这一点。所以除非我遗漏了什么,否则这段代码使用的是无效的迭代器,对吗?当然,这段代码与 gcc 的 libstdc++ 一起工作得很好,但我们都知道,就标准合规性而言,这并不能证明什么。

最佳答案

如果 replace 就地操作,这似乎会起作用。不过,我认为不需要以这种方式实现。所以是的,我会说您的代码在技术上是非法的。

关于c++ - 这是违法的吧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3160882/

相关文章:

c++ - WinAPI 等待管道读取数据

C# 正则表达式 : Capture everything up to

python Pandas : replace a str value of column in another str column with a special character

java - 返回 2 个不同的字符串

java - Arraylist迭代器删除项时并发修改异常

iterator - 如何在不收集到临时向量的情况下对结果的迭代器执行迭代器计算?

c++ - 使用 placement new、malloc 和 free

c++ - STL中hash_map和map的场景区别是什么?

java - 二叉搜索树中序迭代器的 next 方法

C++ 模板 - 成员函数的部分特化