简体   繁体   English

这里是否需要`std :: move`?

[英]Is `std::move` necessary here?

Is std::move necessary in the following snippet? 以下代码段中的std::move必要?

std::function<void(int)> my_std_function;

void call(std::function<void(int)>&& other_function)
{
  my_std_function.swap(std::move(other_function));
}

As far as I know call() accepts a rvalue reference.. but since the rvalue reference is itself an lvalue, in order to call swap(std::function<void(int)>&&) I have to re-cast this to an rvalue reference with std::move 据我所知, call()接受一个右值引用..但是由于右值引用本身就是一个左值,为了调用swap(std::function<void(int)>&&)我必须将其重铸为一个带有std::move的右值引用

Is my reasoning correct or std::move can be omitted in this case (and if it can, why?) 我的推理是正确的还是std::move在这种情况下可以省略(如果可以,为什么?)

std::function::swap does not take its parameter by rvalue reference. std::function::swap不会通过右值引用获取其参数。 It's just a regular non- const lvalue reference . 这只是一个普通的非const左值参考 So std::move is unhelpful (and probably shouldn't compile, since rvalue references aren't allowed to bind to non- const lvalue references). 因此, std::move无用(并且可能不应该编译,因为不允许右值引用绑定到非const左值引用)。

other_function also doesn't need to be an rvalue reference. other_function也不需要是右值引用。

The signature is 签名是

void std::function<Sig>::swap( function& other )

so code should not compile with std::move (msvc has extension to allow this binding :/) 因此代码不应使用std::move编译(msvc具有扩展名以允许此绑定:/)

As you take r-value reference, I think that a simple assignment is what you want in your case: 当您采用r值参考时,我认为您需要的是一个简单的赋值:

std::function<void(int)> my_std_function;

void call(std::function<void(int)>&& other_function)
{
  my_std_function = std::move(other_function); // Move here to avoid copy
}

In this case, it doesn't make a difference as std::function::swap takes a non-const lvalue reference. 在这种情况下,因为std::function::swap采用非常量左值引用而没有区别。 It shouldn't even compile with std::move . 它甚至不应该使用std::move编译。

If you used a function which did allow rvalues, then you would need to call std::move as other_function is an lvalue, even though the type of it is an rvalue reference. 如果您使用的功能, 确实让右值,那么你需要调用std::move作为other_function是一个左值,即使它的类型是右值引用。 For example: 例如:

struct Foo {
    Foo()=default;
    Foo(const Foo&) { std::cout << "copy" << std::endl; }
    Foo(Foo&&) { std::cout << "move" << std::endl; }
};

void bar (Foo&& a) {
    Foo b {a};            //copy
    Foo c {std::move(a)}; //move
}

You are right in a sense — to get an rvalue again you'd need std::move . 从某种意义上来说,您是正确的-要再次获得右值,您需要std::move

However, the swap call doesn't need an rvalue or an rvalue reference — just a plain ol' lvalue ref. 但是, swap调用不需要右值或右值引用,仅需要普通的左值引用。

So you're good to go without the std::move cast. 因此,最好不要使用std::move cast。

In terms of move semantics, a swap operation is pretty low-level. 就移动语义而言,交换操作是非常底层的。 You'll find that most useful moves are ultimately implemented by a series of swaps, so it makes sense that the swaps themselves don't use move semantics. 您会发现,最有用的移动最终是通过一系列交换实现的,因此,交换本身不使用移动语义是有意义的。 Really, how would they? 真的,他们会怎样?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM