C++折叠表达式

折叠表达式(Fold Expressions)是C++17标准引入的,引入折叠表达式的主要目的是计算某个值。这个值的特殊性在于:它与可变参有关,而不是与单独某个可变参有关。换句话说,所有的可变参都参与计算,才能求出该值。在可变参函数模板中,因为展开参数比较麻烦,如果要把传递进来的所有参数加在一起,可能要写很多代码,而通过折叠表达式,只需要一行代码就可以求出所有可变参的和。

template<typename... T>
auto add_val(T... args)
{
    return (... + args);
}

在上面的例子中,return语句后面的括号中就是一个折叠表达式。

折叠表达式一般有4种格式,每种格式都是用圆括号括起。所谓左折就是参数从左边开始计算,右折就是参数从右边开始计算。

一元左折(Unary Left Fold):

格式:(… 运算符 一包参数)

计算方式:(((参数1 运算符 参数2) 运算符 参数3)… 运算符 参数N)

运算符指的是C++语言中的运算符,绝大部分运算符都可以用在这里。

一元右折(Unary Right Fold):

格式:(一包参数 运算符 …)

计算方式:(参数1 运算符 (… (参数N-1 运算符 参数N)))

template<typename... T>
auto sub_val_left(T... args)
{
    return (... - args);
}

template<typename... T>
auto sub_val_right(T... args)
{
    return (args - ...);
}

cout << sub_val_left(10, 20, 30, 40) << endl;  // (((10-20)-30))-40=-80
cout << sub_val_right(10, 20, 30, 40) << endl;  // 10-(20-(30-40))=-20

二元左折(Binary Left Fold):

格式:(init 运算符 … 运算符 一包参数)

计算方式:(((init 运算符 参数1) 运算符 参数2)… 运算符 参数N)

二元右折(Binary Right Fold):

格式:(一包参数 运算符 … 运算符 init)

计算方式:(参数1 运算符 (… (参数N 运算符 init)))

template<typename... T>
auto sub_val_left_b(T... args)
{
    return (200 - ... - args);
}

template<typename... T>
auto sub_val_right_b(T... args)
{
    return (args - ... - 200);
}

cout << sub_val_left_b(10, 20, 30, 40) << endl;  // (((200-10)-20)-30)-40=120
cout << sub_val_right_b(10, 20, 30, 40) << endl;  // 10-(20-(30-(40-200)))=200

template<typename... T>
void print_val_left_b(T... args)
{
    (cout << ... << args);
}
print_val_left_b(10, "abc", 30, "def");  // 10abc30def

Top