考虑这段代码:
void makeNew(std::function<void()>&& func)
{
std::function<void()> p = func;
}
void test(){}
用法:
makeNew(std::bind(test));
预期结果:
临时 std::function<void()>
从 std::bind(test)
的结果类型创建的对象
然后这个临时 std::function 对象作为右值引用传递给 makeNew,然后移动构造函数调用 when std::function p = func;被调用。
实际发生了什么(使用 VS2010 并使用调试器单步执行):
对于下面的语句std::function<void()> p = func;
, 调用复制构造函数而不是移动构造函数。
有人可以解释这种行为吗?
最佳答案
右值引用不是右值(从函数返回时除外)。它只是一种独特的左值类型,具有与普通引用不同的绑定(bind)规则。
如果您想从右值引用移动,请使用 std::move
,与任何其他引用相同。 std::move
返回一个右值引用类型,因此表达式 std::move(func)
是一个 xvalue,因此 是 一个右值并且可以从中移动。 func
是左值,即使它具有右值引用类型。
请注意,很少需要采用右值引用的函数。你这样做是为了排除左值,要么是因为你想完全阻止它们被传入,要么是因为你有一个左值重载来做一些不同的事情。最常见的情况是您希望函数从右值移动或复制左值。因此,您可以改为按值获取参数并从中移动(如 Joseph 的回答),与编写两个不同函数的麻烦相比,开销很小或没有开销。
关于c++ - 未调用 std::function 移动构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21307145/