为什么左侧折叠表达式不反转右侧折叠表达式的输出?

时间:2015-06-13 14:07:50

标签: c++ templates c++14 fold-expression

我正在查看C ++ 17 fold expressions,我想知道为什么以下程序输出

4 5 6 
4 5 6 

用于for_each次调用

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

我认为第二个表达式意味着以相反的顺序输出数字

6 5 4

结果如何相同?

1 个答案:

答案 0 :(得分:8)

根据§14.5.3/ 9

  

fold-expression的实例化产生:

     

(9.1) - ((E1 op E2)op···) op EN for a left fold,

     

(9.2) - E1 op(···op(EN-1 op EN))为一元右折,

     

(9.3) - (((E op E1)op E2)op···)op EN for binary left fold,and

     

(9.4) - E1 op(···op(EN-1 op(EN op E)))用于二进制右折叠

     

在每种情况下,op是折叠运算符,N是包扩展参数中的元素数,每个Ei是通过实例化模式并用第i个元素替换每个包扩展参数来生成的。

在上面的代码中,它们都是一元折叠表达式,它们的扩展是

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))); 
}

因此表达式具有comma operator定义的评估顺序,因此输出相同。

致谢:感谢我的朋友Marco首先提出原始问题并让我有机会解决此潜在误导性问题。