传递具有 std::move 函数签名的向量
Passing vector with std::move function signature
考虑下面的代码
void foo(std::vector<int> v)
{
//do something here
}
//calling the function
vector<int> v1 = {1,2,3};
foo(std::move(v1));
我的问题是,函数 foo 不是应该具有签名 void foo(std::vector<int>&& v)
才能获取向量的 r 值引用吗?
My question is, isnt the function foo supposed to have signature void foo(std::vector<int>&& v)
for it to be able to take the r value reference of the vector?
如果这就是您想要的,那么是的,但这并不意味着您拥有的是不正确的。当您将某些内容传递给函数时,复制会从源中初始化参数。这意味着如果你这样做
vector<int> v1 = {1,2,3};
foo(v1);
然后 foo
获得 v1
的副本。有
vector<int> v1 = {1,2,3};
foo(std::move(v1));
我们从 std::move(v1)
复制初始化 v
并且由于 std::move(v1)
是右值引用,因此为 v
选择移动构造函数并且 v1
被移动进入函数。
因此,通过按值获取,您可以让调用者选择为它提供一个临时对象,为它提供一个右值引用,这将把对象移动到函数中,或者只是让一个副本发生。如果你有 void foo(std::vector<int>&& v)
那么你只能传递一个临时的或 std::move()
一个左值。如果调用者不自己制作一个副本,然后将该副本移动到函数中,就无法允许调用者制作副本。
isn't the function foo supposed to have signature void foo(std::vector<int>&& v)
for it to be able to take the r value reference of the vector?
它是std::vector<int>
的移动构造函数,具有这样的签名。
函数foo()
将std::vector<int>
对象作为参数值:
void foo(std::vector<int> v) {
// ...
}
必须以某种方式构造参数对象v
。传递给foo()
的参数用于构造此参数对象。
通过在表达式foo(std::move(v1))
中调用foo()
,foo()
、v
中的参数对象被move构造.这与在表达式 foo(v1)
中调用 foo()
形成对比,后者导致参数对象 v
被 复制构造 。
因此参数对象的移动构造函数(即v
,一个std::vector<int>
对象)采用std::vector<int>&&
。
void foo(std::vector<int> v)
表示函数接受一个std::vector<int>
对象作为参数。 如何构造这个参数对象取决于调用者,但随后它由foo
.
拥有和使用
在来电者中,您有:
foo(/**compiler constructs the v parameter from whatever is here**/);
因此:
vector<int> v1 = {1,2,3};
foo(v1); // This constructs the parameter `v` as a copy of `v1`.
与
相比
vector<int> v1 = {1,2,3};
foo(std::move(v1)); // This constructs the parameter `v` by moving from the value of `v1`.
两者都有效,但它们做的事情略有不同。
void foo(std::vector<int>&& v)
表示函数接受一个reference作为参数,它引用了别处的std::vector<int>
,也意味着调用者不应该使用该参数在此函数完成后,因为调用者打算以某种方式使其无效。
语言有助于防止此处出现错误
- 强制您传递一个临时值(这样调用者就不会在
foo
完成后不小心尝试使用引用的 vector
的值),
- 或者强迫你调用
std::move
,向编译器保证你不会在foo
完成后尝试使用引用的vector
的值)
考虑下面的代码
void foo(std::vector<int> v)
{
//do something here
}
//calling the function
vector<int> v1 = {1,2,3};
foo(std::move(v1));
我的问题是,函数 foo 不是应该具有签名 void foo(std::vector<int>&& v)
才能获取向量的 r 值引用吗?
My question is, isnt the function foo supposed to have signature
void foo(std::vector<int>&& v)
for it to be able to take the r value reference of the vector?
如果这就是您想要的,那么是的,但这并不意味着您拥有的是不正确的。当您将某些内容传递给函数时,复制会从源中初始化参数。这意味着如果你这样做
vector<int> v1 = {1,2,3};
foo(v1);
然后 foo
获得 v1
的副本。有
vector<int> v1 = {1,2,3};
foo(std::move(v1));
我们从 std::move(v1)
复制初始化 v
并且由于 std::move(v1)
是右值引用,因此为 v
选择移动构造函数并且 v1
被移动进入函数。
因此,通过按值获取,您可以让调用者选择为它提供一个临时对象,为它提供一个右值引用,这将把对象移动到函数中,或者只是让一个副本发生。如果你有 void foo(std::vector<int>&& v)
那么你只能传递一个临时的或 std::move()
一个左值。如果调用者不自己制作一个副本,然后将该副本移动到函数中,就无法允许调用者制作副本。
isn't the function foo supposed to have signature void
foo(std::vector<int>&& v)
for it to be able to take the r value reference of the vector?
它是std::vector<int>
的移动构造函数,具有这样的签名。
函数foo()
将std::vector<int>
对象作为参数值:
void foo(std::vector<int> v) {
// ...
}
必须以某种方式构造参数对象v
。传递给foo()
的参数用于构造此参数对象。
通过在表达式foo(std::move(v1))
中调用foo()
,foo()
、v
中的参数对象被move构造.这与在表达式 foo(v1)
中调用 foo()
形成对比,后者导致参数对象 v
被 复制构造 。
因此参数对象的移动构造函数(即v
,一个std::vector<int>
对象)采用std::vector<int>&&
。
void foo(std::vector<int> v)
表示函数接受一个std::vector<int>
对象作为参数。 如何构造这个参数对象取决于调用者,但随后它由foo
.
在来电者中,您有:
foo(/**compiler constructs the v parameter from whatever is here**/);
因此:
vector<int> v1 = {1,2,3};
foo(v1); // This constructs the parameter `v` as a copy of `v1`.
与
相比vector<int> v1 = {1,2,3};
foo(std::move(v1)); // This constructs the parameter `v` by moving from the value of `v1`.
两者都有效,但它们做的事情略有不同。
void foo(std::vector<int>&& v)
表示函数接受一个reference作为参数,它引用了别处的std::vector<int>
,也意味着调用者不应该使用该参数在此函数完成后,因为调用者打算以某种方式使其无效。
语言有助于防止此处出现错误
- 强制您传递一个临时值(这样调用者就不会在
foo
完成后不小心尝试使用引用的vector
的值), - 或者强迫你调用
std::move
,向编译器保证你不会在foo
完成后尝试使用引用的vector
的值)