Я пытаюсь понять, как использовать пакет параметров в 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
Есть ли общее правило использования пакетов?
Как читать { (std::cout << args, 0)... };
или U(std::forward<Args>(args)...)
? Почему не { (std::cout << args..., 0) }
и U(std::forward<Args>(args...))
?
Первый расширяет содержание круглой скобки; так что становитесь { (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),
и т. д.
Подобно тому, как есть &
для указания побитовой операции и операции и адреса операции, ...
не везде одно и то же. sizeof...
не является пакетом параметров, прикрепленным к оператору sizeof
. sizeof...
- это отдельное ключевое слово / оператор. Все это, «sizeof ...» дает вам размер пакета параметров, который указан по имени в круглых скобках.
С { (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()
ожидает ровно один аргумент).
На странице написано: «Этот раздел не завершен».
До, когда вы его объявляете, после, когда вы его расширяете (используете);
sizeof...(Ts)
- это особый случай: это просто оператор, который знает количество элементов. Если вы находитесь за пределами круглой скобки, разверните ее полное содержание.