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

Почему перемещение захвата не поддерживается в С++ lambda?

Текущий стандарт С++ 11 не поддерживает перемещение захвата переменной в лямбда-выражении, например

unique_ptr<int[]> msg(new int[1000000]);
async_op([&&msg] { // compile error : move capture is not supported
   /* do something */
});

Поскольку передача сообщений и уникальное право собственности играют определенную роль в каком-то асинхронном проектировании системы, я думаю, что перемещение семантики следует рассматривать как семантику семантики первого класса. Но lambda не поддерживает захват перемещения.

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

4b9b3361

Ответ 1

Спецификация С++ пытается быть довольно консервативной. Это очень плохо для следующей спецификации языка, чтобы разорвать программы, которые соответствовали предыдущей спецификации.

Перемещение семантики заняло некоторое время, чтобы созреть. Когда я вспоминаю, произошли изменения уже в 2009 году. Между тем лямбды не были реализованы во многих компиляторах до аналогичных временных рамок. Не было времени, чтобы заполнить пробелы и до сих пор выпускать стандарт в 2011 году, который уже был очень запоздалым. (Прочитайте спецификацию с компиляторами, протестируйте компиляторы, вернитесь и обсудите спецификацию, черновик, прототип, тест, повторите. Проходит некоторое время.)

Lambdas будет значительно расширен в следующем стандарте, получив тип вывода (auto полиморфизм). Xeo упоминает одно возможное решение для перемещения инициализации.

Обратите внимание, что лямбда - это только синтаксический сахар. Они указаны в терминах автоматически определенного класса, но не содержат ничего, что вы не можете сделать сами. Что касается нынешнего языкового стандарта, от вас ожидается, что он будет вручную реализовывать эту реализацию, когда сахар закончится.

Кстати, вы можете обойти отсутствующую функцию, захватив старомодный auto_ptr, который представляет собой устаревшую попытку С++ 03 с умным указателем. Он недействителен его собственным конструктором копирования, в основном реализующим move-on-copy. Но он устарел от С++ 11 и может вызывать предупреждения. Однако вы могли бы попробовать что-то подобное.