Какие правила размещения оператора пакета параметров

Я пытаюсь понять, как использовать пакет параметров в C++, и я пришел к нескольким примерам, что меня смутило, так это размещение пакета operator..., иногда он находится перед именем пакета, иногда после:

template<typename... Ts> void func(Ts... args){
    const int size = sizeof...(args) + 2;  // <====== before
    int res[size] = {1,args...,2};   // <====== after
    // since initializer lists guarantee sequencing, this can be used to
    // call a function on each element of a pack, in order:
    int dummy[sizeof...(Ts)] = { (std::cout << args, 0)... };
}

Иногда внутри скобок, иногда снаружи:

Class c1(&args...);
::new((void *)p) U(std::forward<Args>(args)...) // <==== outside

Есть ли общее правило использования пакетов?

До, когда вы его объявляете, после, когда вы его расширяете (используете); sizeof...(Ts) - это особый случай: это просто оператор, который знает количество элементов. Если вы находитесь за пределами круглой скобки, разверните ее полное содержание.

max66 09.09.2018 04:04

Как читать { (std::cout << args, 0)... }; или U(std::forward<Args>(args)...)? Почему не { (std::cout << args..., 0) } и U(std::forward<Args>(args...))?

fluter 09.09.2018 04:07

Первый расширяет содержание круглой скобки; так что становитесь { (std::cout << arg0, 0), (std::cout << arg1, 0), (std::cout << arg2, 0), и т. д. Второй расширяет вызов до std::forward(), поэтому становится U(std::forward<Arg0>(arg0), std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), и т. д.

max66 09.09.2018 04:11

Подобно тому, как есть & для указания побитовой операции и операции и адреса операции, ... не везде одно и то же. sizeof... не является пакетом параметров, прикрепленным к оператору sizeof. sizeof... - это отдельное ключевое слово / оператор. Все это, «sizeof ...» дает вам размер пакета параметров, который указан по имени в круглых скобках.

Sam Varshavchik 09.09.2018 04:16

С { (std::cout << args..., 0) } вы получаете { (std::cout << arg0, arg1, arg2, 0) }. С U(std::forward<Args>(args...)) это ошибка, потому что вы не расширяете Args, а, например, U(std::forward<int>(args...)) становится U(std::forward<int>(arg0, arg1, arg2)) (это ошибка, когда sizeof...(args) != 1, потому что std::forward() ожидает ровно один аргумент).

max66 09.09.2018 04:22
Документация по синтаксису
Mike Kinghan 09.09.2018 13:00

На странице написано: «Этот раздел не завершен».

fluter 10.09.2018 02:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
54
0

Другие вопросы по теме