C++
Expresiones Fold
Buscar..
Observaciones
Fold Expressions son compatibles con los siguientes operadores
+ | - | * | / | % | \ ˆ | Y | | | << | >> | ||
+ = | - = | * = | / = | % = | \ ˆ = | & = | | = | << = | >> = | = | |
== | ! = | < | > | <= | > = | && | || | , | . * | -> * |
Al plegar una secuencia vacía, una expresión de plegado está mal formada, excepto por los siguientes tres operadores:
Operador | Valor cuando el paquete de parámetros está vacío |
---|---|
&& | cierto |
|| | falso |
, | vacío() |
Pliegues Unarios
Los pliegues únicos se utilizan para plegar paquetes de parámetros sobre un operador específico. Hay 2 tipos de pliegues únicos:
Unary Left Fold
(... op pack)
que se expande de la siguiente manera:((Pack1 op Pack2) op ...) op PackN
Unary Right Fold
(pack op ...)
que se expande de la siguiente manera:Pack1 op (... (Pack(N-1) op PackN))
Aquí hay un ejemplo
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
Pliegues binarios
Los pliegues binarios son básicamente pliegues únicos , con un argumento adicional.
Hay 2 tipos de pliegues binarios:
Doblado izquierdo binario -
(value op ... op pack)
- Expande de la siguiente manera:(((Value op Pack1) op Pack2) op ...) op PackN
Plegado derecho binario
(pack op ... op value)
- Se expande de la siguiente manera:Pack1 op (... op (Pack(N-1) op (PackN op Value)))
Aquí hay un ejemplo:
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
Doblando sobre una coma
Es una operación común la necesidad de realizar una función particular sobre cada elemento en un paquete de parámetros. Con C ++ 11, lo mejor que podemos hacer es:
template <class... Ts>
void print_all(std::ostream& os, Ts const&... args) {
using expander = int[];
(void)expander{0,
(void(os << args), 0)...
};
}
Pero con una expresión de doblez, lo anterior se simplifica muy bien para:
template <class... Ts>
void print_all(std::ostream& os, Ts const&... args) {
(void(os << args), ...);
}
No requiere caldera críptica.