When I am constructing std::function with lambda with captured values it makes an additional copy (move) of those parameters (actually the of the whole lambda object I guess). The code:
#include <iostream>
#include <functional>
// Testing class - just to see constructing/destructing.
class T {
private:
static int idCounter; // The global counter of the constructed objects of this type.
public:
const int id; // Unique object ID
inline T() : id(++idCounter) {
std::cout << " Constuctor Id=" << id << std::endl;
};
inline T(const T& src) : id(++idCounter) {
std::cout << " Copy constructor Id=" << id << std::endl;
}
inline T(const T&& src) : id(++idCounter) {
std::cout << " Move constructor Id=" << id << std::endl;
}
inline void print() const {
std::cout << " Print is called for object with id=" << id << std::endl;
}
inline ~T() {
std::cout << " Destructor Id=" << id << std::endl;
}
};
int T::idCounter=0;
// Declare type of the std::function to store our lambda.
typedef std::function<int (void)> Callback;
int main()
{
std::cout << "Let's the game begin!" << std::endl;
T obj; // Custruct the first object.
std::cout << "Let's create a pointer to the lambda." << std::endl;
// Make a labmda with captured object. (The labmda prints and returns object's id).
// It should make one (local) copy of the captured object but it makes it twice - why?!
const Callback* pcb= new Callback( [obj]() -> int {
obj.print();
return obj.id;
} );
std::cout << "Now let's print lambda execution result." << std::endl;
std::cout << "The functor's id is " << (*pcb)() << std::endl;
std::cout << "Destroying the lambda." << std::endl;
delete pcb;
std::cout << "Terminating." << std::endl;
return 0;
}
The output is:
Let's the game begin! Constuctor Id=1 Let's create a pointer to the lambda. Copy constructor Id=2 Move constructor Id=3 Destructor Id=2 Now let's print lambda execution result. Print is called for object with id=3 The functor's id is 3 Destroying the lambda. Destructor Id=3 Terminating. Destructor Id=1
I made a std:function with lambda with captured object. It should make a local copy of the object for lambda but it make the copy twice (look at move constructor call - highlighted with bold). Actually it make a copy of the whole lambda object. Why? How can I avoid that?
I am using lambdas for inter-thread event processing and they may capture noticeable amounts of date so I am trying to find a way to avoid unnecessary copying. So the task is simple - to pass constructed lambda into the function with minimal expenses - if it will copy data twice for every constructed lambda I would search for another way to work with events.
I am using GCC v4.7.2 forced to GNU C++11.
std::function
. This moving-the-lambda forces the captured object to move as well (i.e recursively moving!)> – Nawaz