When move-constructing a std::function
object from a lambda, where that lambda has by-value captures, it appears that the move-constructor of the object that is value-captured is called twice. Consider
#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; }
The output is
---------
move ctor
move ctor
---------
I work on Mac OS X Catalina and my compiler is
g++-9 (Homebrew GCC 9.3.0) 9.3.0
I compile with g++ -std=c++17
.
I guess this behavior might be somewhat compiler-implementation-dependent, but I am still curious about the mechanism.
Can someone please explain why the move constructor was called twice and what really happened there?
std::thread
and the bound arguments: stackoverflow.com/questions/59601840/… – underscore_dstd::therad
passes its arguments by (forwarding) references, while the constructor ofstd::function
passes its argument by value. – Daniel Langr