Mat*_*att 16 c++ move-semantics c++11
所以,这提供了预期的输出:
void f(std::string&& s)
{
s += " plus extra";
}
int main(void)
{
std::string str = "A string";
f( std::move(str) );
std::cout << str << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
字符串加上额外的
也就是说,当我在Ideone上运行它时,它可以工作,但它是UB吗?在调用之前和之后添加额外的字符串初始化f没有改变任何东西.
How*_*ant 18
这是有效的,而不是UB.
它也是可怕的混淆代码. std::move(s)只不过是对左撇子的阉割.它本身实际上根本不生成任何代码.它的唯一目的是将左值转换为右值,以便客户端代码可以在lvalue/rvalue表达式(string在本例中为)上重载.
对于这种情况,你应该通过lvalue-reference传递:
void f(std::string& s)
{
s += " plus extra";
}
...
f( str );
Run Code Online (Sandbox Code Playgroud)
或者,传递值并返回一个新字符串:
std::string f(std::string s)
{
s += " plus extra";
return s;
}
...
str = f( std::move(str) );
Run Code Online (Sandbox Code Playgroud)
ser*_*gej 10
std::move什么都不动.它表示通过将其参数转换为右值,可以" 移动 " 对象.
您的代码有效,并且没有执行移动操作.
如果你移动构造另一个字符串对象,你将得到str调用后未指定状态的行为.move-constructor执行实际的移动操作.f()s
例:
std::vector<std::string> sv;
void f(std::string&& s)
{
s += " plus extra";
sv.push_back(std::move(s)); // move s (str) into a new object
}
int main(void)
{
std::string str = "A string";
f(std::move(str));
std::cout << str << std::endl; // output: empty string
std::cout << sv.back() << std::endl; // output: "A string plus extra"
return 0;
}
Run Code Online (Sandbox Code Playgroud)
代码有效,因为没有执行实际移动.以下是如何使其无效:
string f(std::string&& s) {
std::string res(std::move(s));
res += " plus extra";
return res;
}
Run Code Online (Sandbox Code Playgroud)
str此调用之后的状态有效,但未指定.这意味着您仍然可以分配一个新值以str将其重新置于有效状态,但如果不调用未指定的行为(演示),您将无法输出它.有关移动状态的详细信息,请参阅此问答.