2015-06-13 8 views
10

ich einen Blick auf C++ 17 fold expressions nehmen und ich frage mich, warum die folgenden Programm Ausgänge tutWarum invertiert ein linker Faltungsausdruck die Ausgabe eines rechten Faltungsausdrucks nicht?

4 5 6 
4 5 6 

für beide der for_each Anrufe

template<typename F, typename... T> 
void for_each1(F fun, T&&... args) 
{ 
    (fun (std::forward<T>(args)), ...); 
} 

template<typename F, typename... T> 
void for_each2(F fun, T&&... args) 
{ 
    (..., fun (std::forward<T>(args))); 
} 

int main() 
{ 
    for_each1([](auto i) { std::cout << i << std::endl; }, 4, 5, 6); 
    std::cout << "-" << std::endl; 
    for_each2([](auto i) { std::cout << i << std::endl; }, 4, 5, 6); 
} 

Live Example

Ich dachte, dass der zweite Falte Ausdruck die Zahlen in umgekehrter Reihenfolge ausgeben sollte

6 5 4 

Wie sind die Ergebnisse gleich?

Antwort

9

Nach 14.5.3/9

Die Instantiierung eines fold-expression § erzeugt:

(9,1) - ((E1 op E2) op · · ·) op EN für eine einstellige links falten,

(9,2) - E1 op (· · · op (EN-1 op DE)) für eine einstellige rechts falten,

(9,3) ((E op E1) op E2) op · · ·) op EN für eine binäre linke Falte und

(9.4) - E1 op (· · · op (EN-1 op (EN op E))) für einen binären rechten Falz

In jedem Fall ist op der faltenoperator, N ist die Anzahl der Elemente in den Packexpansionsparametern, und jedes Ei wird erzeugt, indem das Muster instanziiert und jeder Packexpansionsparameter durch seinen ersetzt wird ites Element.

im Code über sie beide einstellige fold Ausdrücke und ihre Expansion sind, ist

template<typename F, typename... T> 
void for_each1(F fun, T&&... args) { 

    // Unary right fold (fun(args_0) , (fun(args_1) , (fun(args_2) , ...))) 
    (fun (std::forward<T>(args)), ...); 
} 

template<typename F, typename... T> 
void for_each2(F fun, T&&... args) { 

    // Unary left fold ((fun(args_0) , fun(args_1)) , fun(args_2)) , ... 
    (..., fun (std::forward<T>(args))); 
} 

so die Ausdrücke die gleiche Auswerteauftrag haben, wie durch die comma operator definiert und somit ist der Ausgang der gleiche .

Credits: Dank an meinen Freund Marco, die die ursprüngliche Frage an erster Stelle angehoben und gab mir die Chance, diese potentiell irreführende Problem zu lösen.