C++
Сгибание выражений
Поиск…
замечания
Fold Expressions поддерживаются для следующих операторов:
+ | - | * | / | % | \ | & | | | << | >> | ||
+ = | знак равно | знак равно | знак равно | знак равно | \знак равно= | знак равно | | = | << = | >> = | знак равно | |
== | знак равно | < | > | <= | > = | && | || | , | . * | -> * |
При складывании над пустой последовательностью выражение сложения является плохо сформированным, за исключением следующих трех операторов:
оператор | Значение, когда пакет параметров пуст |
---|---|
&& | правда |
|| | ложный |
, | недействительными () |
Унарные складки
Унарные складки используются для сложения пакетов параметров над конкретным оператором. Существует 2 вида унарных складок:
Unary Left Fold
(... op pack)
который расширяется следующим образом:((Pack1 op Pack2) op ...) op PackN
Unary Right Fold
(pack op ...)
который расширяется следующим образом:Pack1 op (... (Pack(N-1) op PackN))
Вот пример
template<typename... Ts>
int sum(Ts... args)
{
return (... + args); //Unary left fold
//return (args + ...); //Unary right fold
// The two are equivalent if the operator is associative.
// For +, ((1+2)+3) (left fold) == (1+(2+3)) (right fold)
// For -, ((1-2)-3) (left fold) != (1-(2-3)) (right fold)
}
int result = sum(1, 2, 3); // 6
Бинарные складки
Двоичные складки в основном унарные складки , с дополнительным аргументом.
Существует два вида двоичных сгибов:
Binary Left Fold -
(value op ... op pack)
- расширяется следующим образом:(((Value op Pack1) op Pack2) op ...) op PackN
Binary Right Fold
(pack op ... op value)
- расширяется следующим образом:Pack1 op (... op (Pack(N-1) op (PackN op Value)))
Вот пример:
template<typename... Ts>
int removeFrom(int num, Ts... args)
{
return (num - ... - args); //Binary left fold
// Note that a binary right fold cannot be used
// due to the lack of associativity of operator-
}
int result = removeFrom(1000, 5, 10, 15); //'result' is 1000 - 5 - 10 - 15 = 970
Складывание запятой
Это общая операция, требующая выполнения определенной функции по каждому элементу в пакете параметров. С C ++ 11 лучшее, что мы можем сделать, это:
template <class... Ts>
void print_all(std::ostream& os, Ts const&... args) {
using expander = int[];
(void)expander{0,
(void(os << args), 0)...
};
}
Но с выражением складки выражение выше упрощает:
template <class... Ts>
void print_all(std::ostream& os, Ts const&... args) {
(void(os << args), ...);
}
Не требуется критический шаблон.