C ++ 17 лямбда-захват с ослабленными требованиями к типу - PullRequest
8 голосов
/ 19 марта 2019

У меня есть следующий код, который компилируется с компилятором C ++ 17, но не с C ++ 14.Мне интересно, что было изменением, которое позволило компилировать следующий код:

struct Foo{
  Foo()=default;
  Foo(const Foo&)=default;// copy by const ref 
};

struct Bar{
  Bar()=default;  
  Bar(Bar&)=default; //copy by non const
};

int main()
{
  Foo foo;
  Bar bar;
  Bar barcpy = bar;
  auto foolam = [foo]{};
  auto barlam = [bar]{}; //compiles only with C++17
}

Есть ли какое-то точное предложение для этого кода для компиляции или это связано с какой-то другой функцией?

1 Ответ

8 голосов
/ 19 марта 2019

Гарантированная копия Elision формулировкой ). Лямбда здесь на самом деле красная сельдь.

В C ++ 14 это:

auto barlam = [bar]{};

по-прежнему требует, чтобы конструкция хода была действительной (даже если вы не хотите, чтобы это движение и в любом случае это движение, скорее всего, было бы отменено). Но эта лямбда не является движущейся конструкцией, потому что Bar не является движущейся конструкцией. Foo является конструируемым на ходу, поэтому foolam работает нормально.

Не лямбда-версия этого будет:

auto bar = Bar{}; // error in C++14
auto foo = Foo{}; // ok

В C ++ 17 это не конструкция перемещения - мы просто напрямую инициализируем целевой объект. В каком-то смысле мы идем по этому пути. С другой стороны, по языковым правилам вообще нет никакого движения. Итак, это:

auto bar = Bar{};

в точности эквивалентно:

Bar bar{};

То же самое относится к лямбде.

...