C++11 如果我有T&&;温度=标准::移动(其他);然后将其用于按值接受T的函数
假设我有一个下面的函数:C++11 如果我有T&&;温度=标准::移动(其他);然后将其用于按值接受T的函数,c++11,move,move-semantics,C++11,Move,Move Semantics,假设我有一个下面的函数: void foo(std::string strParam) // pass-by-value { // function-body } 所以foo(string)的strParam将通过copy(如果arg是左值)或move(如果arg是右值)创建 众所周知, foo("blah"); // rvalue; so string move constructor invoked for strParam. 对, string bar = "blah"; fo
void foo(std::string strParam) // pass-by-value
{
// function-body
}
所以foo(string)的strParam将通过copy(如果arg是左值)或move(如果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.
和用于命名的右值引用变量
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),另一个是命名的右值引用(左值)
没错,对吗?一个更正:
foo("blah"); // rvalue; so string move constructor invoked for strParam.
这实际上调用了采用const char*
的std::string
构造函数,而不是std::string
move构造函数。这是重载集中唯一的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
Update:正如评论中指出的,foo(“blah”)
实际上会调用两个构造函数,就好像它实际上是foo(string(“blah”)
。首先,从“blah”
构造一个临时字符串,并将该临时字符串移动到strParam
中。然而,第二步可能会被省略,因为string strParam(string(“blah”)
是多余的。这可以通过delete
-ing自定义小部件的移动构造函数或使用-fno-elide构造函数编译来验证
或者,正如我喜欢看的那样,我们都是对的。调用常量char*
,并调用字符串move构造函数(~ish?) 在string&&movedBar=move(bar)
&&
代表[universal reference][0][0]中,命名对象被视为左值。要传播对象的右值,必须将其强制转换为右值(即std::move()
)。@erenon它不是一个通用引用(即使在链接的定义中),即使它是,也没关系-它会被推导出为左值引用或右值引用,在这两种情况下,下一行将其视为左值-如果其类型为auto&&(或在模板中涉及类型推断T),则它将是一个通用引用;即使我确实使用auto&&作为它的类型(如果我编写它auto&&movedBar=move(bar)),类型也会被推断为string&&作为右值引用,但它是一个命名的右值引用,所以它是一个lvalue@0x499602D2我发现谈论对象的价值类别令人困惑。值类别是表达式的属性。因此,id表达式movedBar
是左值,函数调用表达式move(bar)
是右值。调用foo(“blah”)
似乎需要const char*
构造函数和move构造函数。但是,移动构造函数可能会被省略。我试着用std::string
重写代码,替换为一个自定义小部件
类,该类具有=delete
ed移动构造函数。