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.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow