折叠表达式是C++17新引进的语法特性。使用折叠表达式可以简化对C++11中引入的参数包的处理,从而在某些情况下避免使用递归。
折叠表达式共有四种语法形式。分别为一元的左折叠和右折叠,以及二元的左折叠和右折叠。
语法形式中的op代表运算符,pack代表参数包,init代表初始值。
初始值在右边的为右折叠,展开之后从右边开始折叠。而初始值在左边的为左折叠,展开之后从左边开始折叠。
不指定初始值的为一元折叠表达式,而指定初始值的为二元折叠表达式。
当一元折叠表达式中的参数包为空时,只有三个运算符(&& || 以及逗号)有缺省值,其中&&的缺省值为true,||的缺省值为false,逗号的缺省值为void()。
下面看看具体应用
假设我们想写一个能接受一个及以上参数的求和函数,
#include <iostream>
using namespace std;
template<typename First>
First sum1(First&& value)
{
return value;
}
template<typename First, typename Second, typename... Rest>
First sum1(First&& first, Second&& second, Rest&&... rest)
{
return sum1(first + second, forward<Rest>(rest)...);
}
template<typename First, typename... Rest>
First sum2(First&& first, Rest&&... rest)
{
return (first + ... + rest);
}
int main()
{
cout << sum1(1) << sum1(1, 2) << sum1(1, 2, 3) << endl; // 136
cout << sum2(1) << sum2(1, 2) << sum2(1, 2, 3) << endl; // 136
}
#include <iostream>
using namespace std;
template<typename... Args>
bool all(Args... args) {return (... && args);}
template<typename... Args>
bool any(Args... args) {return (... || args);}
int main()
{
cout << boolalpha << all(true, false, true) << endl; // false
cout << boolalpha << any(true, false, true) << endl; // true
cout << boolalpha << all() << endl; // true
cout << boolalpha << any() << endl; // false
}
#include <iostream>
using namespace std;
template<typename... Ts>
void printAll(Ts&&... mXs)
{
(cout << ... << mXs) << endl;
}
template<typename TF, typename... Ts>
void forArgs(TF&& mFn, Ts&&... mXs)
{
(mFn(mXs), ...);
}
int main()
{
printAll(3, 4.0, "5"); // 345
printAll(); // 空行
forArgs([](auto a){cout << a;}, 3, 4.0, "5"); // 345
forArgs([](auto a){cout << a;}); // 空操作
}