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

Может ли пакет параметров быть зафиксирован неявно в С++ 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);

Является ли стандарт четко обозначенным в любом месте, что это не должно быть хорошо сформировано?

4b9b3361

Ответ 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). Кажется, вам интересно, когда вам разрешено или не ссылаться на идентификатор пакета параметров внутри лямбда.

Вы можете думать так же об ссылочных переменных во внешней области, поскольку у вас может быть доступ к ним, но даже не может быть разрешено получить доступ к идентификатору исходной переменной.

Они такие же эфирные, как пакеты параметров.