美文网首页
C++17:folder expression(折叠表达式)

C++17:folder expression(折叠表达式)

作者: fck_13 | 来源:发表于2020-01-11 14:06 被阅读0次

(1)先举一个不是很恰当的例子给大家看一下折叠表达式具体是怎么使用的:

int sum_1_to_5()
{
  return (1 + 2 + 3 + 4 + 5);
}

sum_1_to_5();

我们使用

template<typename ...Args>
int sum(Args&&... args) 
{
    return (args + ... + 0); 
}

sum(1, 2, 3, 4, 5);

也就是说折叠表达式能够自动的将指定的操作应用于形参包。(args + ... + 0) 等价于(1+2+3+4+5+0)
折叠表达式在一定的程度上可以简化代码。
(2)语法

( pack op ... )                 (1) 
( ... op pack )                 (2) 
( pack op ... op init ) (3) 
( init op ... op pack ) (4) 

pack指的是参数包,op指的是具体的操作,init指的是具体的初始值。上述的语法等价于
(1) 称为一元右折叠:unary right fold
(2) 称为一元左折叠:unary left fold
(3) 称为二元右折叠:binary right fold
(4) 称为二元左折叠:binary left fold
上述的表达式等价于:
(E op ...) <=> (E1 op (... op (E N-1 op EN))) (1)
(... op E) <=> (((E1 op E2) op ...) op EN) (2)
(E op ... op I) <=> (E1 op (... op (EN−1 op (EN op I)))) (3)
(I op ... op E) <=> ((((I op E1) op E2) op ...) op EN) (4)
E 为有N个元素的参数包,op为具体的操作符,I为初始值。在(3),(4)中,两个op一定要是一样的。

需要比较值得重点关注的一点是,二元op的取值范围为
+-*/%^&|=<><<>>+=-=*=/=%=^=&=|=<<=>>===!=<=>=&&||,.*->*

再给大家两个比较简单的例子

#include <iostream>
#include <vector>

//(1) ( pack op ... )
template<class T, class... Args>
void push_back_vec(std::vector<T>& v, Args&&... args)
{
    static_assert((std::is_constructible_v<T, Args&> && ...));
    (v.push_back(args), ...);
}

//(4) (init op ... op pack)
template<class ...Args>
void printer(Args&&... args)
{
    (std::cout << ... << args) << '\n';
}

int main()
{
    std::vector<int> v;
    push_back_vec(v, 6, 2, 45, 12);
    for (int i : v) std::cout << i << ' ';   //6 2 45 12
    std::cout << "\n";
    
    printer(1, 2, 3, "abc");   //123abc
    return 0;
}

几个需要注意的点:

  1. 只有三个运算符允许pack为空, &&||,&&true||false,void()
template <typename... Args>
auto empty_pack_unary_fold_operator_and(Args&&... args){
    return (args && ...);
}

template <typename... Args>
auto empty_pack_unary_fold_operator_or(Args&&... args){
    return (args || ...);
}

template <typename... Args>
auto empty_pack_unary_fold_operator_comma(Args&&... args){
    return (args , ...);
}

TEST_CASE("a unary fold is used with a pack expansion of length zero", "fold expression"){
    CHECK(true == empty_pack_unary_fold_operator_and());
    CHECK(false == empty_pack_unary_fold_operator_or());
    using void_type = decltype(empty_pack_unary_fold_operator_comma());
    CHECK( std::is_void<void_type>::value );
}
  1. 注意运算符的优先级。

相关文章

  • C++17:folder expression(折叠表达式)

    (1)先举一个不是很恰当的例子给大家看一下折叠表达式具体是怎么使用的: 我们使用 也就是说折叠表达式能够自动的将指...

  • EL表达式

    EL表达式语法 ${ EL expression}其中:$ 表示EL表达式的开始。EL expression指定...

  • iOS 常用的lldb命令

    一、expression expression命令的作用是执行一个表达式,并将表达式返回的结果输出。express...

  • Web 基础16 JSP之EL 入门

    1.1 EL表达式的概述   全称是Expression Language   EL(Expression Lan...

  • 常用LLDB调试指令

    help help beakpoint expression 执行一个表达式 expression self.vi...

  • 2021-12-15

    b标题表达式 // 表达式 expression(titleData, config, currentFull...

  • LLDB

    常用命令 expression expression命令的作用是执行一个表达式,并将表达式返回的结果输出。expr...

  • 巧用css expression表达式解决IE6的下before

    IE6支持在css样式中使用 expression表达式,所以,可以针对IE6,使用expression表达式,通...

  • 7.5 C控制语句:条件运算符

    如果expression1为真,取expression2值,否则取expression3值 绝对值表达式

  • Spring AOP

    Pointcut expression【切面表达式】 expressiondesignatorsexecution...

网友评论

      本文标题:C++17:folder expression(折叠表达式)

      本文链接:https://www.haomeiwen.com/subject/mabvactx.html