首页 > 编程语言 > 详细

C++17 Fold Expressions

时间:2020-09-03 19:14:25      阅读:61      评论:0      收藏:0      [点我收藏+]

C++17 Fold Expressions

本文介绍C++17新特性折叠表达式。文章示例代码通过MinGW编译,宏__cplusplus=201703

下面我们从一个模板函数sum开始,介绍折叠表达式。

用折叠表达式简化以前的代码

C++11引入了变长参数模板,我们想求变长参数的和,可以这样写模板函数

template <typename T>
auto sum(T arg){
    return arg;
}

template <typename T1, typename... T>
auto sum(T1 arg, T... args){
    return arg + sum(args...);
}

int main() {
    std::cout<<sum(1,2,3)<<std::endl;
    return 0;
}

注:这里用到了auto推导,C++14编译没问题。用C++11编译的读者记得在函数签名后面加"-> T"

为了完成sum这个函数,我们需要写2个函数。一个进行递归,一个作为递归返回条件。这种模板的递归是在编译时发生的,遇到复杂的递归会大大加大编译时间。有没有办法写一个模板函数,同时又能实现sum功能呢?

有,就是折叠表达式

我们看下折叠表达式的写法

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

int main() {
    std::cout<<sum_folder(1,2,3)<<std::endl;
    return 0;
}

这里折叠表达式会将sum_folder(1,2,3)扩展成(1+(2+3))

如何使用折叠表达式

看了上面的例子,相信读者对折叠表达式已经有了直观的认识。下面我们详细介绍下折叠表达式的使用。

一元折叠

假设参数是args,操作符是op。一元折叠有两种情况:左折叠和右折叠

  1. unary left fold: (... op args) expends to ((arg1 op arg2) op arg3) + ...
  2. unary right fold: (args op ...) expends to arg1 op (arg2 op ... (argN-1 op argN))

举2个例子方便理解

左折叠

template<typename... T>
string combine_str_left(T... args) {
    return (... + args);
}

string s("head");
// expand to (s+" ") + "tail"
std::cout<<combine_str_left(s," ","tail")<<std::endl;

右折叠

template<typename... T>
string combine_str_right(T... args) {
    return (args + ...);
}

右折叠就不能combine_str_right(s," ", "tail")这么写,因为扩展开来是s + (" " + "tail")显然两个字面值是不能直接相加的。所以比起右折叠,左折叠用的比较多。

二元折叠

  1. binary left fold: (value op ... op args) expand to ((value op arg1) op arg2) op ...
  2. binary right fold: (args op ... op value) expand to args1 op (arg2 op ... ( argN op value))

C++17 Fold Expressions

原文:https://www.cnblogs.com/pusidun/p/13608761.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!