使用 std::move 函数签名传递向量

Kra*_*ken 6 c++ rvalue-reference move-semantics

考虑下面的代码

void foo(std::vector<int> v)
{
   //do something here
}
//calling the function
vector<int> v1 = {1,2,3};
foo(std::move(v1));
Run Code Online (Sandbox Code Playgroud)

我的问题是,函数 foo 不是应该有签名void foo(std::vector<int>&& v)才能获取向量的 r 值引用吗?

Nat*_*ica 6

我的问题是,函数 foo 是否应该具有签名void foo(std::vector<int>&& v)才能获取向量的 r 值引用?

如果那是您想要的,那么是的,但这并不意味着您拥有的不正确。当您将某些内容传递给函数时,复制会从源中初始化参数。这意味着如果你这样做

vector<int> v1 = {1,2,3};
foo(v1);
Run Code Online (Sandbox Code Playgroud)

然后foo得到一份v1. 和

vector<int> v1 = {1,2,3};
foo(std::move(v1));
Run Code Online (Sandbox Code Playgroud)

我们复制 initialize vfromstd::move(v1)并且因为std::move(v1)是一个右值引用,所以选择移动构造函数v并将其v1移动到函数中。

因此,通过按值获取,您可以为调用者提供一个选项:给它一个临时的,给它一个右值引用,这两者都会将对象移动到函数中,或者只是让复制发生。如果你有void foo(std::vector<int>&& v)那么你只能传递一个临时或std::move()左值。没有办法允许调用者在没有他们自己制作副本然后将该副本移动到函数中的情况下制作副本。

  • @Kraken `std::move` 只是一个将您提供的内容转换为右值引用的函数。然后,将该右值引用传递给“foo”,编译器将使用它来初始化“v”。由于它是右值引用,因此该类型与向量移动构造函数匹配,因此将调用移动构造函数而不是复制构造函数。合理? (2认同)