Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VC++ 15 calls the wrong copy constructor for lambda capture?

Consider the following program:

#include <iostream>
struct X {
  X () = default;
  X (X &) { std::cout << "non-const called" << std::endl; }
  X (X const &) { std::cout << "const called" << std::endl; }
  int i () const { return 7; }
};

auto f () {
  X x;
  auto lambda = [=]() { return x.i(); };
  return lambda;
}

int main()
{
  auto lambda = f();
  std::cout << lambda () << std::endl;
  return 0;
}

With VC++15, I get the output

const called
const called
7

With Clang 3.9, I get

non-const called
7

Which compiler is correct here?

like image 381
JohnB Avatar asked Dec 03 '16 16:12

JohnB


1 Answers

I would say that clang is right.
The most suited constructor is called only once when the lambda captures x and the constructor for the returned value is optimized out.
That's why you obtain only one non-const called.


See here and here for further details about copy-elision and RVO.

like image 71
skypjack Avatar answered Nov 16 '22 03:11

skypjack