您所质疑的表达式的行为已由标准明确定义,并且是实现所必需的。该标准的相关章节如下:
C++11 § 21.4.8.1-11
template<class charT, class traits, class Allocator>
basic_string<charT,traits,Allocator>
operator+(const basic_string<charT,traits,Allocator>& lhs,
const charT* rhs);
回报:lhs + basic_string<charT,traits,Allocator>(rhs)
这将导致:
C++11 § 21.4.8.1-3
template<class charT, class traits, class Allocator>
basic_string<charT,traits,Allocator>
operator+(const basic_string<charT,traits,Allocator>& lhs,
basic_string<charT,traits,Allocator>&& rhs);
回报:std::move(rhs.insert(0, lhs))
最后...
C++11 § 21.4.2-22
basic_string<charT,traits,Allocator>&
operator=(basic_string<charT,traits,Allocator>&& str) noexcept;
效果:如果 *this 和 str 不是同一个对象,则修改 *this,如表 71 所示。 [注意:有效的实现是 swap(str)。——尾注]
换句话说,为+
运算符的 rhs 创建一个临时对象,然后使用 修改右值引用rhs.insert(0,lhs)
,最后将结果发送到赋值运算符的右值引用版本,它可以有效地执行移动操作。
有关详细信息,请参阅标准的相关部分。
C++03x 笔记
有人要求我为 C++03x 提供相同的演练。我对该标准的最后(官方)版本并不肯定,但以下内容基于 ISO/IEC 14882:2003(E) 作为参考。自行决定使用。
C++03x 也定义了类似的演练,如下所述,标准的相关部分已适当注明。
C++03x § 21.3.7.1-5
template<class charT, class traits, class Allocator>
basic_string<charT,traits,Allocator>
operator+(const basic_string<charT,traits,Allocator>& lhs, const charT* rhs);
回报:lhs + basic_string<charT,traits,Allocator>(rhs)
因此,就像 C++11 一样,临时是从表达式的rhs构造的。从那里...
C++03x § 21.3.7.1-1
template<class charT, class traits, class Allocator>
basic_string<charT,traits,Allocator>
operator+(const basic_string<charT,traits,Allocator>& lhs,
const basic_string<charT,traits,Allocator>& rhs);
返回:basic_string(lhs).append(rhs)
这里我们与 C++11 不同。我们构造一个临时的lhs ,然后使用成员函数附加给定的rhs(第一步的临时) 。append()
为简洁起见,我省略了lhs临时的 const-reference 构造函数。这将我们带到......
C++03x § 21.3.5.2-1
basic_string<charT,traits,Allocator>&
append(const basic_string<charT,traits>& str);
回报:append(str, 0, npos)
这会将调用转发给相关的成员函数,该函数接受来自 rhs 的开始和停止索引,从中进行枚举。这需要我们...
C++03x § 21.3.5.2-2..5
basic_string& append(const basic_string& str, size_type pos, size_type n);
要求:pos <= str.size()
抛出:如果 pos > str.size(),则为 out_of_range。
效果:将要附加的字符串的有效长度 rlen 确定为 n 和 str.size() - pos 中的较小者。然后,如果 size() >= npos - rlen,该函数会抛出 length_error。否则,该函数将由 *this 控制的字符串替换为长度为 size() + rlen 的字符串,其第一个 size() 元素是由 *this 控制的原始字符串的副本,其余元素是初始元素的副本str 控制的字符串,从位置 pos 开始。
返回:*this。
本质上,这会对位置参数进行一些完整性检查,然后用连接的内容执行替换。最后,既然已经完成了分配的rhs,我们可以对整个惨败的目标执行分配操作,这将我们带到......
C++03x § 21.3.1-16
basic_string<charT,traits,Allocator>&
operator=(const basic_string<charT,traits,Allocator>& str);
效果:如果*this和str不是同一个对象,修改*this如表43所示
返回:*this
表 43 表示以下所需的效果。
data()
- 指向数组的已分配副本的第一个元素,该数组的第一个元素由str.data()
size()
- str.size()
capacity()
- 至少和size()
我对此的评估是,实现可以做它想要达到的效果(在表 43 中;仍然需要此处显示的实现路径)。
我太累了,无法进入 C++98。我希望这已经足够了。