Mar*_* A. 10 c++ templates c++14 fold-expression
我正在看看C++ 17 折叠表达式,我想知道为什么以下程序输出
4 5 6
4 5 6
Run Code Online (Sandbox Code Playgroud)
对于这两个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);
}
Run Code Online (Sandbox Code Playgroud)
我认为第二个折叠表达式意味着以相反的顺序输出数字
6 5 4
Run Code Online (Sandbox Code Playgroud)
为什么结果是一样的?
根据§14.5.3/ 9
fold-expression的实例化产生:
(9.1) - ((E1 op E2)op···) op EN for a left left fold,
(9.2) - E1 op(···op(EN-1 op EN))用于一元右折,
(9.3) - (((E op E1)op E2)op···)op EN表示二进制左折叠,和
(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)));
}
Run Code Online (Sandbox Code Playgroud)
因此表达式具有与逗号运算符定义的相同的评估顺序,因此输出相同.
致谢:感谢我的朋友Marco首先提出了原始问题并给了我解决这个潜在误导性问题的机会.