Подтвердить что ты не робот

VС++ 15 вызывает неправильный конструктор копирования для лямбда-захвата?

Рассмотрим следующую программу:

#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;
}

С VС++ 15 я получаю вывод

const called
const called
7

С Clang 3.9 я получаю

non-const called
7

Какой компилятор здесь верен?

4b9b3361

Ответ 1

Я бы сказал, что clang прав.
Наиболее подходящий конструктор вызывается только один раз, когда лямбда захватывает x, а конструктор для возвращаемого значения оптимизируется.
Вот почему вы получаете только один неконстантный вызов.


Смотрите здесь и здесь для получения дополнительной информации о копировании -elision и RVO.