2017-01-13 3 views
21

C++ 17 добавит копия этого объекта по значению, с a capture specification of [*this].C++ 17 лямбда-захват * это

Как это полезно? Как это отличается от захвата this? Не может ли это уже достигнуто в C++ 14 с [tmp = *this]?


Bonus для объяснения, почему P0018R3 использует [=, tmp = *this] вместо [tmp = *this] в их примере. Если бы они использовали [tmp = *this], все перечисленные недостатки решения C++ 14 были бы устранены.

+3

Я думаю, они слишком упростили примеры. Когда вы добавите дополнительные локальные переменные или параметры, вы захотите их скопировать. Тогда часть '[=, ..]' имеет смысл (если вы не хотите их явно фиксировать один за другим, то есть). – dyp

ответ

18

Как это полезно? Это полезно, когда вам нужна копия *this - например, когда *this сам по себе недействителен к моменту оценки лямбда.

Как он отличается от захвата this? Он делает копию объекта, так что, когда вычисляется лямбда, его указатель this ссылается на копию, а не на исходный объект.

Возможно ли это в C++ 14 с [tmp = *this]? Он может, но [*this] более удобен, так как код можно перемещать без префикса доступа члена с помощью tmp.. В противном случае, особенно с [=, tmp = *this], можно случайно обратиться к членам оригинального объекта, когда вы хотели сослаться на копию (особенно, если у вас есть привычка вырезать + вставить программирование). [=,*this] - более безопасная альтернатива в этом случае, поскольку оригинал this недоступен.

1

Представьте, что *this - класс дескриптора, который поддерживает shared_ptr в какое-то общее состояние.

Общий импортер (например) - конечный автомат обработчика протокола.

Класс дескриптора передается через ряд асинхронных обработчиков, поэтому сам должен быть скопирован. Каждый обработчик мутирует общее состояние.

Прочный вариант использования для этого может быть обработчиком протокола для использования с пользовательским сервисом asio (например, http_protocol_socket).

[=, tmp = *this] будет беспорядочные захватить любые переменные значения, в том числе, а опасно, сам this указатель, а также специально захватывая *this в tmp.

В этом случае случайным образом было бы непреднамеренно ссылаться на в обработчике async, потому что это скорее всего будет висящим указателем. Это ошибка, ожидающая появления.

[tmp=*this] будет снимать только *this.

Смежные вопросы