-
一元折叠表达式
( pack op ... )
: 一元右折叠(E op ...)
展开后:(E1 op (... op (EN-1 op EN)))
( ... op pack )
:一元左折叠(... op E)
展开后:(((E1 op E2) op ...) op EN)
-
二元折叠表达式
( 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)
-
折叠表达式
op
支持如下二元操作符:+ - * / % ^ & | = < > << >> += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || , .* ->*
-
当一元折叠表达式的元素个数为
0
(空包)时,只能使用下列运算符:- 逻辑与(
&&
),空包的默认值为true
- 逻辑或(
||
),空包的默认值为false
- 逗号运算符(
,
),空包的默认值为void()
- 逻辑与(
-
当二元折叠表达式中的
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 }
-
一些示例:
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
参考: