Как компилятор генерирует замыкание из лямбды удаленного-по-умолчанию-ctor? - PullRequest
1 голос
/ 22 апреля 2020

Я хочу знать, как можно использовать лямбду с конструктором по умолчанию:

[](){}; // how is this translated by the compiler?

Но это не работает:

auto l = [](){std::cout << "lambda expr\n";}; // which ctor is invoked?

decltype (l) g; // doesn't work
  • Потому что до C ++ 20 он не работал, а C ++ 20 делает лямбда-конструктор по умолчанию.

  • Если нет конструктора для вызова, как получается, что этот объект существует ?

Ответы [ 2 ]

2 голосов
/ 22 апреля 2020

Это немного похоже на вопрос: если int не имеет конструктора, то откуда берется объект int при вычислении целочисленного литерала?

Компилятор может создавать объекты без вызова конструктора просто путем генерации сборки или машинного кода, который требуется для установки объекта в памяти. Он просто не позволяет ВАМ создавать объекты различных типов классов без вызова конструктора. (Хотя в C ++ 20 это изменится благодаря P0593 .)

Когда компилятор видит выражение, содержащее лямбда-выражение, он просто идет вперед и генерирует код который устанавливает объект замыкания в памяти. Не обязательно упаковывать этот код как функцию, как будет упакован код в конструкторе. Возможно даже, что компилятор генерирует некоторый конструктор, который только он знает, как вызывать. С точки зрения пользователя, конструктор не задействован.

1 голос
/ 22 апреля 2020

Компилятор не пишет C ++; он не подчиняется тем же правилам, что и мы.

До C ++ 20 мы не могли по умолчанию конструировать тип замыкания с использованием C ++. Но это не меняет того факта, что стандарт говорит, что лямбда-выражение создает объект типа замыкания. Таким образом, компилятор должен заставить его делать это, и ему никогда не нужно было go через конструктор по умолчанию, чтобы сделать это. Хорошо! Никогда не было никаких правил, в которых говорилось бы, что нужно использовать такую ​​технику.

Извините, что нет более удовлетворительного ответа, но на самом деле это просто "потому что так говорится в стандарте".

Смотрите также: почему компилятор может определить встроенный тип (например, int), когда мы не можем? Потому что!

...