如果我有 T&& temp = std::move(other);然后在按值接受 T 的函数上使用它

if i have T&& temp = std::move(other); then use this on a function that accepts T by value

假设我有以下功能:

void foo(std::string strParam) // pass-by-value
{
    // function-body
}

因此 foo(string) 的 strParam 将通过复制(如果 arg 是左值)或移动(如果 arg 是右值)创建。

众所周知,

foo("blah"); // rvalue; so string move constructor invoked for strParam.

string bar = "blah";
foo(bar); // lvalue; so string copy constructor invoked for strParam.

再次,

string bar = "blah";
foo(move(bar)); // xvalue; so move constructor.

并且对于named右值引用变量

string &&temp = // can be whatever
foo(temp); // *named* rvalue reference IS a lvalue; so copy constructor.

所以我猜这是什么意思,

string &&movedBar = move(bar);
foo(movedBar); // it actually invokes copy constructor.

如此调用,

foo(move(bar)) 

不同于

string&& movedBar = move(bar);
foo(movedBar)

因为一个是未命名的右值引用(xvalue)而另一个是命名的右值引用(lvalue)

没错吧?

一次更正:

foo("blah"); // rvalue; so string move constructor invoked for strParam.

这个 实际上 调用 std::string 构造函数,它采用 const char* 而不是 std::string 移动构造函数。这是重载集中唯一的 std::string 构造函数 - 其他一切都将涉及不止一个用户定义的转换。

在其他所有观点上,您都是正确的。总结一下:

foo("blah"); // calls string constructor that takes a const char*
foo(bar); // calls string copy ctor
foo(move(bar)); // calls string move ctor

string&& movedBar = move(bar);
foo(movedBar); // calls copy ctor

更新:正如在评论中指出的那样,foo("blah")实际上会调用两个构造函数,就好像它实际上是 foo(string("blah"))。首先从 "blah" 构造一个临时字符串,然后将该临时字符串移入 strParam。然而,第二步可能会被省略,因为 string strParam(string("blah")) 是多余的。这可以通过 delete-ing 自定义小部件的移动构造函数或使用 -fno-elide-constructors 进行编译来验证。

或者,正如我喜欢看的那样,我们都是正确的。 const char* 被调用 并且 字符串移动构造函数被调用(~ish?)。