我目前正在学习有关所有c ++ 11/14功能的信息,并想知道何时在函数调用中使用std :: move。
我知道在返回局部变量时不应该使用它,因为这会破坏返回值的优化,但是我真的不明白在函数调用中将值转换为rvalue真正有帮助。
Vit*_*meo 13
当一个函数接受一个右值引用时,您必须提供一个右值(通过已有一个prvalue或std::move用于创建一个xvalue)。例如
void foo(std::string&& s);
std::string s;
foo(s); // Compile-time error
foo(std::move(s)); // OK
foo(std::string{}) // OK
Run Code Online (Sandbox Code Playgroud)
当一个函数接受一个值时,您可以std::move用来移动构造函数参数而不是复制构造。例如
void bar(std::string s);
std::string s;
bar(s); // Copies into `s`
bar(std::move(s)); // Moves into `s`
Run Code Online (Sandbox Code Playgroud)
当函数接受转发引用时,您可以使用std::move来允许该函数将对象进一步向下移动到调用堆栈中。例如
template <typename T>
void pipe(T&& x)
{
sink(std::forward<T>(x));
}
std::string s;
pipe(s); // `std::forward` will do nothing
pipe(std::move(s)); // `std::forward` will move
pipe(std::string{}); // `std::forward` will move
Run Code Online (Sandbox Code Playgroud)
当您有一些实质性的对象,并且将其作为参数传递给函数(例如API或容器emplace操作)时,您将不再需要它在调用站点,因此您想转移所有权,而不是转移所有权复制后立即“丢失”原始文件。那是当您移动它时。
void StoreThing(std::vector<int> v);
int main()
{
std::vector<int> v{1,2,3,4,5,6/*,.....*/};
StoreThing(v);
}
// Copies `v` then lets it go out of scope. Pointless!
Run Code Online (Sandbox Code Playgroud)
与:
void StoreThing(std::vector<int> v);
int main()
{
std::vector<int> v{1,2,3,4,5,6/*,.....*/};
StoreThing(std::move(v));
}
// Better! We didn't need `v` in `main` any more...
Run Code Online (Sandbox Code Playgroud)
如果未应用RVO,则在返回局部变量时会自动发生这种情况(请注意,自C ++ 17以来就强制执行了这样的“优化”操作,因此您可以说std::move在这种情况下添加“冗余” 实际上可以有害)。
同样,std::move如果您传递的是很小的东西(特别是不能具有move构造函数的非类的东西,更不用说有意义的东西了),或者您知道您正在传递给一个接受其参数const-ly 的函数,这也是没有意义的。; 在这种情况下,您是否要保存std::move不会引起任何影响的附加源代码取决于您自己:这从表面上看是明智的,但是在模板中,您可能不确定。