当从lambda中移动构造
#include <functional> #include <iostream> struct Foo { int value = 1; Foo() = default; Foo(const Foo &) {} Foo(Foo &&) { std::cout << "move ctor" << std::endl; } }; int main() { Foo foo; auto lambda = [=]() { return foo.value; }; std::cout << "---------" << std::endl; std::function<int()> func(std::move(lambda)); std::cout << "---------" << std::endl; return 0; }
输出为
---------
move ctor
move ctor
---------
我在Mac OS X Catalina上工作,我的编译器是
g++-9 (Homebrew GCC 9.3.0) 9.3.0
我使用
我猜这种行为可能有点依赖于编译器实现,但我仍然对其机制感到好奇。
有人能不能请解释一下为什么移动构造函数被调用了两次,那里到底发生了什么?
这是由
struct Lambda
{
Lambda() = default;
Lambda(const Lambda&) { std::cout << "C"; }
Lambda(Lambda&&) { std::cout << "M"; }
void operator()() const { }
};
int main()
{
auto lambda = Lambda();
std::function<void()> func(std::move(lambda));
}
它打印出
现场演示:https://godbolt.org/z/xihndc
在您的示例中,该lambda的
为什么
template< class F >
void function( F f )
{
F* ptr = new F(std::move(f));
delete ptr;
}
此代码:
auto lambda = Lambda();
function(std::move(lambda));
然后执行两个动作。
现场演示:https://godbolt.org/z/qzvvwa
我认为,这是因为 只要用 产出: 如果不是move构造的,它将复制参数,而参数又复制captures变量。请参阅:https://godbolt.org/z/yydqg_#include <iostream>
struct Foo
{
int value = 1;
Foo() = default;
Foo(const Foo&) { std::cout << "Foo: copy ctor" << std::endl; }
Foo(Foo&&)
{
std::cout << "Foo: move ctor" << std::endl;
}
};
template<typename T>
class MyFunction
{
T mCallable;
public:
explicit MyFunction(T func)
// if mCallable{ func}, it is copy constructor which has been called
: mCallable{ std::move(func) }
{}
};
int main()
{
Foo foo;
auto lambda = [=]() { return foo.value; };
std::cout << "---------" << std::endl;
MyFunction<decltype(lambda)> func(std::move(lambda));
std::cout << "---------" << std::endl;
return 0;
}
Foo: copy ctor
---------
Foo: move ctor
Foo: move ctor
---------