【发布时间】:2015-03-24 09:17:44
【问题描述】:
我最近发现需要将std::string 的内容替换为其自身的子字符串。我认为在这里调用的最合乎逻辑的函数如下,来自http://www.cplusplus.com/reference/string/string/assign/:
子字符串 (2) string& assign (const string& str, size_t subpos, size_t sublen);
复制从字符位置 subpos 开始并跨越 sublen 个字符的 str 部分(或者直到 str 的结尾,如果 str 太短或 sublen 是 string::npos)。str
另一个字符串对象,其值被复制或移动。subpos
str 中作为子字符串复制到对象的第一个字符的位置。如果这大于 str 的长度,则抛出 out_of_range。注意:str 中的第一个字符由值 0(不是 1)表示。sublen
要复制的子字符串的长度(如果字符串较短,则复制尽可能多的字符)。 string::npos 的值表示直到 str 结尾的所有字符。
但是,我不确定这是否允许,或者它是否会损坏字符串数据。例如,我知道memcpy() 不允许(或至少不保证在这种情况下不会损坏)用自身的(一部分)覆盖内存区域(请参阅memcpy() vs memmove())。但是不知道上面的方法有没有同样的限制。
更一般地说,如果我应该能够自己找出这个问题的答案,你能评论一下吗?我链接到的文档中没有任何内容可以让我清楚地知道这个问题的答案是什么,除了 也许 str 参数描述中的限定符“Another”(“另一个 字符串对象”),这似乎暗示它不能是 this 对象,尽管我不认为这是明确的。这是文档中的弱点吗?
【问题讨论】:
-
Assignable C++ 类通常以安全的方式实现复制赋值运算符(即检查分配
*this = *this)。标准容器类也不例外。 然而, 即使这不是必需的——字符串的子字符串不再是字符串本身。同样,“Cplusplus.com”网站的措辞似乎很糟糕——cppreference.com 使用了“替换”这个词,从中很明显你所做的事情应该是安全的。 -
@TheParamagneticCroissant,为什么“替换”这个词清楚地表明它应该是安全的?同样,您可以说
memcpy()替换了目标缓冲区的内容,但这并不意味着它是安全的。 -
@bgoldst 我很确定标准没有完全涵盖这种情况,因此很难处理。如果您想保持安全,请使用
substr和赋值运算符(即使用副本)。 -
@dyp 不幸的是,这还不够。也许这应该成为 EWG 问题的主题。
-
@Columbo 我怀疑它最终可能会像LWG 526。