1

My reference is to the code segment presented as part of the follow-up discussion on the below write-up:

Lambdas vs. Closures

The pertinent code segment is

struct PrintD
{
~PrintD()
{
cout << "dtor" << endl;
}
};

int main()
{
PrintD d;
auto f = [d](){
d;
};

cout << "--" << endl;

return 0;
}

When the above code is compiled using GCC without the -fno-elide-constructors option, the following output is generated:

--
dtor
dtor

When recompiled using the -fno-elide-constructors option, the following output is generated:

dtor
--
dtor
dtor

Is the understanding correct that in the latter case, the additional dtor print out corresponds to the temporary being destroyed, which is created during the capture of d by copy inside f?

user9196120
  • 381
  • 3
  • 9

1 Answers1

0

The "extra" copy comes from the copy-initialization of f from the lambda (the lambda is a prvalue).

Since C++17's change to prvalue materialization, there is never any extra copy here. You should find that if compiling with -std=c++17 you never get the extra copy, even passing the elision flag.

A simpler code demonstrating the same issue would be auto f = PrintD();.


In C++14 you could mandate avoiding the copy by:

auto&& f = [d] () {d;};

although personally I'd trust the compiler to do it and assume we'll be moving onto C++17 soon enough.

M.M
  • 138,810
  • 21
  • 208
  • 365