Может ли пакет параметров быть зафиксирован неявно в С++ 11 lambdas?
Кто-нибудь знает, правильно ли сформирован следующий неявный захват 'ts':
template<class ... Ts> void bar(Ts ... ts) { }
template<class ... Ts> int foo(Ts ... ts) {
auto L = [=] () {
bar(ts...);
};
L();
return 0;
}
int g = foo(1, 2, 3);
Является ли стандарт четко обозначенным в любом месте, что это не должно быть хорошо сформировано?
Ответы
Ответ 1
14.5.3/6:
Создание экземпляра пакета, не являющегося выражением sizeof...
, создает список E1, E2,..., EN, где N - количество элементов в параметрах расширения пакета. Каждый Ei генерируется путем создания экземпляра шаблона и замены каждого параметра расширения пакета его i-м элементом. Все Ei становятся элементами в прилагаемом списке.
Независимо от того, разрешено ли вам явно собирать пакет (вы можете, используя [ts ...]
), общее правило расширения приведет к захвату каждого элемента списка.
Ответ 2
Я предполагаю, что он хорошо сформирован, я не нашел прямого утверждения (иногда для некоторых ситуаций формулировка нечеткости/иллюстрации), но я предполагаю, что это можно сделать:
§5.1.2/23:
Захват, за которым следует многоточие, является расширение пакета (14.5.3). [Пример:
template<class... Args>
void f(Args... args) {
auto lm = [&, args...] { return g(args...); };
lm();
}
- конец примера]
- Захват, за которым следует многоточие, подразумевает
args
, в лямбда-захвате, является примером захвата (в данном случае явного), и примечательным фактом является то, что args
является идентификатором пакета параметров. В этом коротком параграфе есть единственная задача описать, как lambda-capture захватывают разложения пакетов, которые демонстрируют пакеты параметров, которые могут быть захвачены, хотя его цель заключается не в том, чтобы позволить им быть захвачен.
§5.1.2/12:
Объект зафиксирован, если он зафиксирован явно или неявно. [...]
§ 3/3:
Объект - это значение, объект, ссылка, функция, перечислитель, тип, член класса, шаблон, специализация шаблона, пространство имен, пакет параметров или это.
Из этого я предполагаю, что пакеты параметров являются объектами, которые могут быть захвачены явно или неявно, и поэтому должны применяться те же правила захвата, что и для обычных переменных, за исключением того, что пакеты параметров должны быть соответственно расширены.
Я думаю, что ваш вопрос (и та же аргументация) может быть применен одинаково хорошо для ссылочных переменных, например (Не указано, нужна ли ссылка для хранения. §8.3.2/4). Кажется, вам интересно, когда вам разрешено или не ссылаться на идентификатор пакета параметров внутри лямбда.
Вы можете думать так же об ссылочных переменных во внешней области, поскольку у вас может быть доступ к ним, но даже не может быть разрешено получить доступ к идентификатору исходной переменной.
Они такие же эфирные, как пакеты параметров.