C++11增加了一个新特性可变模版参数(variadic template),它可以接受任意个模版参数在参数包中,参数包是三个点…,它不能直接展开,需要通过一些特殊的方法才能展开,导致在使用的时候有点难度。现在C++17解决了这个问题,让参数包的展开变得容易了,Fold expression就是方便展开参数包的。
fold expression的语义
fold expression有4种语义:
- unary right fold (pack op …)
- unary left fold (… op pack)
- binary right fold (pack op … op init)
- binary left fold (init op … op pack)
其中pack代表变参,比如args,op代表操作符,fold expression支持32种操作符:
引用
+ - * / % ^ & | = > += -= *= /= %= ^= &= |= >= == != = && || , .* ->*
1
|
+
-
*
/
%
^
&
|
=
>
+=
-=
*=
/=
%=
^=
&=
|=
>=
==
!=
=
&&
||
,
.
*
->
*
|
unary right fold的含义
fold (E op …) 意味着 E1 op (… op (EN-1 op EN)).
顾名思义,从右边开始fold,看它是left fold还是right fold我们可以根据参数包…所在的位置来判断,当参数包…在操作符右边的时候就是right fold,在左边的时候就是left fold。我们来看一个具体的例子:
template<typename... Args> auto add_val(Args&&... args) { return (args + ...); } auto t = add_val(1,2,3,4); //10
1
2
3
4
5
6
|
template
<
typename
.
.
.
Args
>
auto
add_val
(
Args
&&
.
.
.
args
)
{
return
(
args
+
.
.
.
)
;
}
auto
t
=
add_val
(
1
,
2
,
3
,
4
)
;
//10
|
right fold的过程是这样的:(1+(2+(3+4))),从右边开始fold。