C char 与使用索引访问的 C++ 字符串元素有何不同

How C char is different from C++ string element accessed using index

我正在使用 C++ erase remove idiom 并遇到一个奇怪的问题。 如果我使用字符串索引访问元素结果不符合预期。

   string str = "A man, a plan, a canal: Panama";
   str.erase(remove(str.begin(), str.end(), str[1]), str.end());

结果:阿曼,计划,运河:Panaa

如果我如下使用,结果如预期。

   string str = "A man, a plan, a canal: Panama";
   str.erase(remove(str.begin(), str.end(), ' '), str.end());

结果:Aman,aplan,acanal:Panama

std::remove的签名:

template< class ForwardIt, class T >
ForwardIt remove( ForwardIt first, ForwardIt last, const T& value );

value 由 const 引用传递,因此在删除第一个 space 后,您的 str[1] 指向错误的内存。在修改容器的同时访问容器元素是不安全的。

算法std::remove声明如下

template<class ForwardIterator, class T>
ForwardIterator remove(
    ForwardIterator first, ForwardIterator last,
    const T& value // <-- reference!
);

如您所见,第三个参数被声明为引用 const T& value

所以在这次通话中

str.erase(remove(str.begin(), str.end(), str[1]), str.end());

第三个参数是对对象 str[1] 的引用,当遇到第一个字符 ' ' 时,其值在算法中更改为字母 'm'..

如果你会写例如

str.erase(remove(str.begin(), str.end(), str[1] + 0), str.end());

您会得到预期的结果,因为在这种情况下引用指的是一个临时对象。