您可以将 std::string 的子字符串分配给它自己吗?
Can you assign a substring of a std::string to itself?
我最近发现需要用它自己的子字符串替换 std::string
的内容。我认为在这里调用的最合乎逻辑的函数如下,来自 http://www.cplusplus.com/reference/string/string/assign/:
substring (2) string& assign (const string& str, size_t subpos, size_t sublen);
Copies the portion of str that begins at the character position subpos and spans sublen characters (or until the end of str, if either str is too short or if sublen is string::npos).
str
Another string object, whose value is either copied or moved.
subpos
Position of the first character in str that is copied to the object as a substring. If this is greater than str's length, it throws out_of_range. Note: The first character in str is denoted by a value of 0 (not 1).
sublen
Length of the substring to be copied (if the string is shorter, as many characters as possible are copied).
A value of string::npos indicates all characters until the end of str.
但是,我不确定这是否允许,或者它是否会破坏字符串数据。例如,我知道 memcpy()
不允许(或者至少在这种情况下不保证不损坏)用自身(的一部分)覆盖内存区域(参见 memcpy() vs memmove()) .但是不知道上面的方法有没有同样的限制。
更笼统地说,如果我自己应该能够找出这个问题的答案,您能发表评论吗?我链接到的文档中没有任何内容让我清楚这个问题的答案是什么,除了 perhaps [=13= 的描述中的限定词 "Another" ] 参数(“Another 字符串对象”),这似乎暗示它不能是 this 对象,虽然我不认为那是明确的。这是文档中的弱点吗?
没有
此操作由 [string::assign]/4:
定义
basic_string& assign(const basic_string& str, size_type pos,
size_type n = npos);
Effects: Determines the effective length rlen
of the string to assign
as the smaller of n
and str.size() - pos
and calls assign(str.data() + pos rlen)
.
(dat typo)
然后:
basic_string& assign(const charT* s, size_type n);
Effects: Replaces the string controlled by *this
with a string
of length n
whose elements are a copy of those pointed to by s
.
这并没有说明 str.assign(str, 0)
是否完全安全(特别是,我们无法知道 何时 每个角色的副本会发生! ).
因此我强烈建议您避免这样做。
不要那样做。
它可能有效,但正如所选答案中所建议的那样,不能保证安全。在最好的情况下,根据您的实现,将创建一个临时对象然后销毁。
一种模拟方法,它不会创建临时对象,而且确实比调用 assign
和 substr
更快:
void trimTo(string & s, size_t pos = 0, size_t len = string::npos)
{
s.erase(pos + len);
s.erase(pos, len);
}
然后,
trimTo(myString, fromPos, numChars);
作为
工作
myString.assign(myString.substr(fromPos, numChars);
但它至少快两倍。
显然这与 operator= 的决定相同(防止自我赋值)。
_Myt& assign(const _Myt& _Right,
size_type _Roff, size_type _Count = npos)
{ // assign _Right [_Roff, _Roff + _Count)
_Right._Check_offset(_Roff);
_Count = _Right._Clamp_suffix_size(_Roff, _Count);
if (this == &_Right)
erase((size_type)(_Roff + _Count)), erase(0, _Roff); // substring
else if (_Grow(_Count))
{ // make room and assign new stuff
_Traits::copy(this->_Myptr(),
_Right._Myptr() + _Roff, _Count);
_Eos(_Count);
}
return (*this);
}
我最近发现需要用它自己的子字符串替换 std::string
的内容。我认为在这里调用的最合乎逻辑的函数如下,来自 http://www.cplusplus.com/reference/string/string/assign/:
substring (2) string& assign (const string& str, size_t subpos, size_t sublen);
Copies the portion of str that begins at the character position subpos and spans sublen characters (or until the end of str, if either str is too short or if sublen is string::npos).str
Another string object, whose value is either copied or moved.subpos
Position of the first character in str that is copied to the object as a substring. If this is greater than str's length, it throws out_of_range. Note: The first character in str is denoted by a value of 0 (not 1).sublen
Length of the substring to be copied (if the string is shorter, as many characters as possible are copied). A value of string::npos indicates all characters until the end of str.
但是,我不确定这是否允许,或者它是否会破坏字符串数据。例如,我知道 memcpy()
不允许(或者至少在这种情况下不保证不损坏)用自身(的一部分)覆盖内存区域(参见 memcpy() vs memmove()) .但是不知道上面的方法有没有同样的限制。
更笼统地说,如果我自己应该能够找出这个问题的答案,您能发表评论吗?我链接到的文档中没有任何内容让我清楚这个问题的答案是什么,除了 perhaps [=13= 的描述中的限定词 "Another" ] 参数(“Another 字符串对象”),这似乎暗示它不能是 this 对象,虽然我不认为那是明确的。这是文档中的弱点吗?
没有
此操作由 [string::assign]/4:
定义basic_string& assign(const basic_string& str, size_type pos, size_type n = npos);
Effects: Determines the effective length
rlen
of the string to assign as the smaller ofn
andstr.size() - pos
and callsassign(str.data() + pos rlen)
.
(dat typo)
然后:
basic_string& assign(const charT* s, size_type n);
Effects: Replaces the string controlled by
*this
with a string of lengthn
whose elements are a copy of those pointed to bys
.
这并没有说明 str.assign(str, 0)
是否完全安全(特别是,我们无法知道 何时 每个角色的副本会发生! ).
因此我强烈建议您避免这样做。
不要那样做。
它可能有效,但正如所选答案中所建议的那样,不能保证安全。在最好的情况下,根据您的实现,将创建一个临时对象然后销毁。
一种模拟方法,它不会创建临时对象,而且确实比调用 assign
和 substr
更快:
void trimTo(string & s, size_t pos = 0, size_t len = string::npos)
{
s.erase(pos + len);
s.erase(pos, len);
}
然后,
trimTo(myString, fromPos, numChars);
作为
工作myString.assign(myString.substr(fromPos, numChars);
但它至少快两倍。
显然这与 operator= 的决定相同(防止自我赋值)。
_Myt& assign(const _Myt& _Right,
size_type _Roff, size_type _Count = npos)
{ // assign _Right [_Roff, _Roff + _Count)
_Right._Check_offset(_Roff);
_Count = _Right._Clamp_suffix_size(_Roff, _Count);
if (this == &_Right)
erase((size_type)(_Roff + _Count)), erase(0, _Roff); // substring
else if (_Grow(_Count))
{ // make room and assign new stuff
_Traits::copy(this->_Myptr(),
_Right._Myptr() + _Roff, _Count);
_Eos(_Count);
}
return (*this);
}