I have trouble understanding what is going on here with calls to C(const C&) and ~C()
So, I make a lambda that captures by value, and then return it. As I understand, each returned lambda has it's own context (the trace is consistent with that claim).
However, according to stroustrup describing of lambda as a function object shortcut (in 11.4.1 of C++ 4th ed), I would expect one copy only to be made for the captured variable, and it does not seem to be the case.
here is my code
//g++ 5.4.0
#include <functional>
#include <iostream>
using namespace std;
class C{
float f;
public:
C(float f): f(f){ cout << "#build C(" << f << ")\n"; }
C(const C& c): f(c.f+0.1){ cout << "#copy C(" << f << ")\n"; }
~C(){ cout << "#destroy C(" << f << ")\n"; }
void display() const { cout << "this is C(" << f << ")\n"; }
};
std::function<void(void)> make_lambda_val(int i){
C c{i};
return [=] () -> void { c.display(); } ;
}
int main(){
cout << "/**trace\n\n";
cout << "--- ?? ---\n";
{
auto l0 = make_lambda_val(0);
auto l1 = make_lambda_val(1);
auto l2 = make_lambda_val(2);
cout << "ready\n";
l0();
l1();
l2();
}
cout << "\n*/\n";
}
and the corresponding trace: (with my comment)
/**trace
--- ?? ---
#build C(0)
#copy C(0.1) <<--| 2 copies ??
#copy C(0.2) <<--|
#destroy C(0.1) <---- one of which is already discarded ?
#destroy C(0)
#build C(1)
#copy C(1.1)
#copy C(1.2)
#destroy C(1.1)
#destroy C(1)
#build C(2)
#copy C(2.1)
#copy C(2.2)
#destroy C(2.1)
#destroy C(2)
ready
this is C(0.2) <---- the second copy is kept ?
this is C(1.2)
this is C(2.2)
#destroy C(2.2)
#destroy C(1.2)
#destroy C(0.2)
*/