1. 一元折叠表达式

    • ( pack op ... ) : 一元右折叠
      • (E op ...) 展开后: (E1 op (... op (EN-1 op EN)))
    • ( ... op pack ) :一元左折叠
      • (... op E) 展开后: (((E1 op E2) op ...) op EN)
  2. 二元折叠表达式

    • ( pack op ... op init ) :二元右折叠
      • (E op ... op I) 展开后: (E1 op (... op (EN−1 op (EN op I))))
    • ( init op ... op pack ) :二元左折叠
      • (I op ... op E) 展开后: ((((I op E1) op E2) op ...) op EN)

    二元折叠

  3. 折叠表达式 op 支持如下二元操作符: + - * / % ^ & | = < > << >> += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || , .* ->*

  4. 当一元折叠表达式的元素个数为 0 (空包)时,只能使用下列运算符:

    • 逻辑与(&&),空包的默认值为 true
    • 逻辑或(||),空包的默认值为 false
    • 逗号运算符(,),空包的默认值为 void()
  5. 当二元折叠表达式中的 init 的运算符优先级高于 op 运算符时,要用 ()init 表达式括起来

    template<typename ...Args>
    int sum(Args&&... args)
    {
        //  return (args + ... + 1 * 2);   // Error: operator with precedence below cast
        return (args + ... + (1 * 2)); // OK
    }
    
  6. 一些示例:

    template<typename ... Ts>
    auto sum(Ts ... ts){
        // 右折叠( ... 在操作符右侧)1+(2+(3+(4+5)))
        // return (ts + ...);
        // 左折叠(... 在操作符左侧) (((1+2)+3)+4)+5
        return (... + ts);
    }
    // 匹配范围内的单个元素
    template <typename T, typename ... Ts> 
    auto matches(const T& range, Ts ... ts) { 
        return (std::count(std::begin(range), std::end(range), ts) + ...); 
    }
    // 检查集合中的多个插入操作是否成功
    template <typename T, typename ... Ts> 
    bool insert_all(T& set, Ts ... ts) { 
        return (set.insert(ts).second && ...); 
    }
    // 检查所有参数是否在范围内
    template <typename T, typename ... Ts> 
    bool within(T min, T max, Ts ...ts) { 
        return ((min <= ts && ts <= max) && ...); 
    }
    // 将多个元素插入vector中
    template <typename T, typename ... Ts> 
    void insert_all(std::vector<T> &vec, Ts ... ts){ 
        (vec.push_back(ts), ...); 
    }
    // 打印
    template<typename... Ts>
    void my_printf(Ts ... ts) {
        ((std::cout << ts << std::endl), ...);
    }
    int main()
    {
        int x = sum(1,2,3,4,5);
        cout << x << endl;
        string y = sum(string("abc"),string("def"),string("gh"));
        cout << y << endl;
        auto z = sum(1, 2.2f, 3.3, 'a');
        cout << z << endl;
    
        std::vector<int> v{1, 2, 3, 4, 5}; 
        int c = 0;
        c = matches(v, 2, 5); // return 2 
        cout << c << endl;
        c = matches(v, 100, 200); // return 0 
        cout << c << endl;
        c = matches("abcdefg", 'x', 'y', 'z'); // return 0
        cout << c << endl; 
        c = matches("abcdefg", 'a', 'b', 'f'); // return 3
        cout << c << endl;
    
        std::set<int> my_set{1, 2, 3}; 
        insert_all(my_set, 4, 5, 6); // Returns true 
        for_each(my_set.begin(), my_set.end(), [](const auto &t){cout << t << " ";});
        cout << endl;
        insert_all(my_set, 7, 2, 8); // Returns false, because the 2 collides 
                                    // 由于短路,8并没有被插入
        for_each(my_set.begin(), my_set.end(), [](const auto &t){cout << t << " ";});  
        cout << endl;
    
        bool b = false;
        b = within(10, 20, 1, 15, 30); // --> false 
        cout << boolalpha << b << endl;
        b = within(10, 20, 11, 12, 13); // --> true 
        cout << b << endl;
        b = within(5.0, 5.5, 5.1, 5.2, 5.3); // --> true
        cout << b << endl;
        std::string aaa {"aaa"}; 
        std::string bcd {"bcd"}; 
        std::string def {"def"}; 
        std::string zzz {"zzz"}; 
        b = within(aaa, zzz, bcd, def); // --> true 
        cout << b << endl;
        b = within(aaa, def, bcd, zzz); // --> false
        cout << b << endl;
    
        std::vector<int> my_vec{1, 2, 3}; 
        insert_all(my_vec, 4, 5, 6);
        for_each(my_vec.begin(), my_vec.end(), [](const auto &t){cout << t << " ";});  
        cout << endl;
        return 0;
    }
    

    输出:

    15
    abcdefgh
    103.5
    2
    0
    0
    3
    1 2 3 4 5 6 
    1 2 3 4 5 6 7 
    false
    true
    true
    true
    false
    1 2 3 4 5 6 
    

参考:

fold expression