Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 连接两个移动的字符串_C++_C++11_Move Semantics - Fatal编程技术网

C++ 连接两个移动的字符串

C++ 连接两个移动的字符串,c++,c++11,move-semantics,C++,C++11,Move Semantics,代码如下: #include <iostream> #include <string> using namespace std; int main() { string s1 = "hello"; string s2 = "my"; string s3 = "world"; string s4; s4 = move(s1) + move(s2) + move(s3); cout << "s4(" <<

代码如下:

#include <iostream>
#include <string>
using namespace std;

int main() {
    string s1 = "hello";
    string s2 = "my";
    string s3 = "world";
    string s4;
    s4 = move(s1) + move(s2) + move(s3);
    cout << "s4(" << s4 << ") = s1(" << s1 << ") + s2(" << s2 << ") + s3(" << s3 << ")"<< endl;
}
你能解释一下发生了什么事吗?使用XCode 4.6.1进行测试

编辑: 我希望看到: s4hellomyworld=s1+s2+s3

s4=moves1+moves2+moves3实际上是operator=s4,operator+operator+moves1,moves2,moves3; 运算符+的实现不需要修改其右值参数,但是允许的。大概实现是这样的:

string operator+(string&& left, string&& right)
{
   string result(left);
   return result += right;
}
此处仅读取右侧。

s4=moves1+moves2+moves3实际上是operator=s4,operator+operator+moves1,moves2,moves3; 运算符+的实现不需要修改其右值参数,但是允许的。大概实现是这样的:

string operator+(string&& left, string&& right)
{
   string result(left);
   return result += right;
}
其中右键是只读的。

我假设您期望s4hellomyworld=s1+s2+s3

首先,移动会使源对象处于有效状态,并带有一个未指定的值[C++11:21.4.2/2]——也就是说,您不能声明从源对象移动后字符串的值是什么

其次,std::move用词不当,因为它实际上不移动任何东西。移动是通过交换东西来实现的,并且不能保证您的字符串操作符+会做任何类似的事情—请参阅jmihalicza的答案以获取示例实现;move所做的一切就是获取一个可以从中移动的右值引用

[C++11:21.4.6.3/1]谈到std::basic_string&assignbasic_string&str noexcept,这是您真正调用的函数,当您遵循operator+的所有breadcrumbs时,有效的实现是swapstr,但这并不意味着必须进行交换。

我假设您期望的是s4hellomyworld=s1+s2+s3

首先,移动会使源对象处于有效状态,并带有一个未指定的值[C++11:21.4.2/2]——也就是说,您不能声明从源对象移动后字符串的值是什么

其次,std::move用词不当,因为它实际上不移动任何东西。移动是通过交换东西来实现的,并且不能保证您的字符串操作符+会做任何类似的事情—请参阅jmihalicza的答案以获取示例实现;move所做的一切就是获取一个可以从中移动的右值引用

[C++11:21.4.6.3/1]介绍了std::basic_string&assignbasic_string&str noexcept,这是您真正调用的函数,当您遵循operator+的所有breadcrumbs时,有效的实现是swapstr,但这并不意味着必须进行交换

因此,似乎在连接期间,rhss保持不变。在s1处累积所有字符串后,s4的移动分配将清空s1


因此,似乎在连接期间,rhss保持不变。在s1处累积所有字符串后,s4的移动分配将清空s1。

请习惯于描述您预期会发生的情况。你的理解可能和我们的理解不一样,事实上,因为你在这里问一个问题来解决你的困惑,它可能不是!请习惯于描述你期望发生的事情。你的理解可能和我们的理解不一样,事实上,因为你在这里问一个问题来解决你的困惑,它可能不是!如果要返回引用,为什么要创建临时结果变量?请注意,标准不返回引用。如果要返回引用,为什么要创建临时结果变量?请注意,标准不返回引用
template<class _CharT, class _Traits, class _Allocator>
_LIBCPP_INLINE_VISIBILITY inline
basic_string<_CharT, _Traits, _Allocator>
operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, basic_string<_CharT, _Traits,  _Allocator>&& __rhs)
{
    return _VSTD::move(__lhs.append(__rhs));
}