考虑下面的代码
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值引用?
我的问题是,函数foo是否应该具有签名
void foo(std::vector<int>&& v)
以使其能够采用向量的r值引用?
如果这是您想要的,那么是的,但这并不意味着您拥有的是不正确的。当您将某些东西传递给函数时,复制会从源中初始化参数。也就是说,如果您这样做
vector<int> v1 = {1,2,3};
foo(v1);
然后foo
获得v1
的副本。带有
vector<int> v1 = {1,2,3};
foo(std::move(v1));
我们从v
复制初始化std::move(v1)
,并且由于std::move(v1)
是右值引用,因此为v
选择了移动构造函数,并且v1
被移入了函数。
因此,通过按值获取,您可以给调用者一个选项,使其成为临时对象,为它提供右值引用,这既会将对象移入函数中,也可以只是进行复制。如果您有void foo(std::vector<int>&& v)
,则只能传递一个临时值或std::move()
一个左值。没有调用者自己制作的副本,然后将其移动到函数中的方法,将无法使调用者进行复制。
通过将foo()
称为foo(std::move(v1))
,即v
中的形式参数对象foo()
void foo(std::vector<int> v)
是已移动构造。这是foo
的移动构造函数,它需要一个std::vector<int>&&
。
如here所述,如果满足以下所有条件,则编译器将创建一个默认的移动运算符: