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());
您会得到预期的结果,因为在这种情况下引用指的是一个临时对象。
我正在使用 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());
您会得到预期的结果,因为在这种情况下引用指的是一个临时对象。