Могу ли я захватить объект как const при использовании init caputre? - PullRequest
0 голосов
/ 03 марта 2020

При использовании захвата инициализации C ++ 14 применяются правила удержания типа 'auto' (которые отбрасывают ссылку, const и volatile)

Обратите внимание, что Я не говорю о ссылке const . Если я хотел получить ссылку на константу, я мог бы написать:

auto lambda = [&widget = std::as_const(widget)] () {};
// C++17

Или я могу добавить & к lhs, чтобы привести Rhs в качестве ссылки на констант.

я спрашиваю: могу ли я напишите что-нибудь вроде этого?

1011 *

1 Ответ

3 голосов
/ 03 марта 2020

Нет способа захватить объект по значению и иметь значение const. Грамматика для init-capture равна

init-capture:
    identifier initializer
    & identifier initializer

, где identifier равна

identifier:
    identifier-nondigit
    identifier identifier-nondigit
    identifier digit

Это означает, что вы можете указать только имя, без каких-либо cv-квалификаторов. Для не изменяемой лямбды это не проблема, поскольку функция будет const, и вы не сможете изменить захват по значению объекта.

Для изменяемой лямбды вы можете захватить ссылку на const, подобную вам. делать с [&widget = std::as_const(widget)]. Если вы не можете или не хотите иметь ссылку, вам нужно написать const-оболочку, такую ​​как

template <typename T>
class const_wrapper
{
    const T obj;
public:
    const_wrapper(T obj) : obj(obj) {}
    operator const T&() const { return obj; }
};

Вышеуказанный объект является копируемым, но не назначаемым (из-за члена const) и только разрешает постоянный доступ к базовому типу.

...