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

С++ 17 лямбда-захват * это

С++ 17 добавит копирование этого объекта по значению с спецификацией захвата [*this].

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


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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

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

[tmp=*this] будет захватывать только *this.