Доступ к С++ 14 lambda захватывает как элементы структуры - программирование
Подтвердить что ты не робот

Доступ к С++ 14 lambda захватывает как элементы структуры

AFAIK, С++ 11/14 не позволяет на месте определять новый тип возвращаемого значения при определении лямбда. Однако, похоже, выражение Camba capture lambda С++ 14 по существу создает анонимный тип с одним или несколькими "членами" и оператором(). Итак, почему компилятор не разрешает доступ к захваченным членам из вне лямбда. Мой слабый ум не может справиться с сложностями С++, но звучит ли он как разумное расширение языка? Вот пример.

vector<string> words = { "Stack", "Overflow" };
auto l = [w = words](){}; // almost like a C# anonymous type
cout << l.w[0]; // does not work. 
4b9b3361

Ответ 1

Статус-кво

Это обсуждалось, когда лямбда-init-capture были добавлены к языку. Текущий рабочий проект стандарта (N3797) говорит (в [expr.prim.lambda] p11):

Для каждого захвата init в типе закрытия объявляется нестатический элемент данных, названный идентификатором init-capture.

В стандарте не указывается доступ к этому члену, что делает его непонятным, действительно ли это:

auto x = [n(0)] {};
int k = x.n; // ok?

Эта и некоторые другие проблемы с заданиями с init-capture привели к национальному комментарию GB3 по стандартному проекту, который обрабатывается основной рабочей группой С++ в качестве основной проблемы 1760. При обсуждении этого вопроса основная рабочая группа решила, что лавровые init-capture не должны быть доступными членами объекта замыкания.

Решение для выпуска 1760 (которое одобрено CWG, но еще не полным комитетом) изменяет спецификацию, вместо этого скажет:

Выполнение init-capture ведет себя так, как будто оно объявляет и явно захватывает переменную формы "auto init-capture ;", декларативная область которой представляет собой составное выражение лямбда-выражения [...]

Эта новая формулировка дает понять, что init-capture не добавляет именного элемента закрывающего объекта, а вместо этого действует как любой другой захват лямбды.

Как расширение языка

Доступ к init-capture будет доступным членам типа закрытия, безусловно, возможно (и моя первоначальная реализация init-capture в clang сделала это, прежде чем я внедрил решение проблемы 1760). Это также похоже на полезную функцию, но это также допустило бы нарушение инкапсуляции лямбда-выражений в общем случае, когда init-capture не должны быть видимыми.

Ответ 2

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

Это невозможно по дизайну

5.1.2 [expr.prim.lambda]

     

15 [...] Для каждого объекта, захваченного копией, объявленный нестатический элемент данных объявляется в типе замыкания. Порядок объявления этих членов не указан. [...]

     

16 [...] Не указано, являются ли дополнительные неназванные нестатические элементы данных   объявленный в типе замыкания для объектов, захваченных ссылкой.

Захваченные переменные не имеют названия (или, по крайней мере, имеют имена, которые невыразимые смертными), и их заказ на объявление преднамеренно неопределенные. Захваты по ссылке могут даже не существовать в закрытии тип.

Смелый акцент мой.