fold expression
折叠表达
减少%28褶皱阿参数包在二进制运算符上。
句法
( pack op ... ) | (1) | (since C++17) |
---|---|---|
( ... op pack ) | (2) | (since C++17) |
( pack op ... op init ) | (3) | (since C++17) |
( init op ... op pack ) | (4) | (since C++17) |
1%29一元右褶
2%29元左折
3%29二元右折
4%29双左折叠
op | - | any of the following 32 binary operators: + - * / % ^ & | = < > << >> += -= *= /= %= ^= &= |= <<= >>= == != <= >= && || , .* ->*. In a binary fold, both ops must be the same. |
---|---|---|
pack | - | an expression that contains an unexpanded parameter pack and does not contain an operator with precedence lower than cast at the top level (formally, a cast-expression) |
init | - | an expression that does not contain an unexpanded parameter pack and does not contain an operator with precedence lower than cast at the top level (formally, a cast-expression) |
请注意,打开和结束括号是折叠表达式的一部分。
解释
的实例化折叠表达
扩展表达式e
详情如下:
1%29一元右折叠%28 E OP...%29变为E
1 OP%28...OP%28 E
N-1执行部分E
N%29%29
2%29一元左折%28...OP E%29变为%28%28 E
1执行部分E
2%29 OP...%29执行部分E
n
3%29二进制右折叠%28 E OP...OP I%29变为E
1 OP%28...OP%28 E
N-1OP%28E
执行部分I%29%29%29
4%29二进制左折叠%28 i op...op E%29变为%28%28%28 i op E
1%29执行部分E
2%29 OP...%29执行部分E
n
%28其中N是包扩展%29中的元素数。
例如,
二次
template<typename... Args>
bool all(Args... args) { return (... && args }
bool b = all(true, true, true, false
// within all(), the unary left fold expands as
// return ((true && true) && true) && false;
// b is false
二次
当一个一元折叠与长度为零的包展开一起使用时,只允许以下运算符:
1%29逻辑和%28&&
29%。空包的值是true
2%29逻辑或%28||
29%。空包的值是false
3%29逗号运算符%28,
29%。空包的值是void()
注
如果用作init或Pack的表达式具有一个优先于顶级CAST的操作符,则可以将其括号内:
二次
template<typename ...Args>
int sum(Args&&... args) {
// return (args + ... + 1 * 2 // Error: operator with precedence below cast
return (args + ... + (1 * 2) // OK
}
二次
例
二次
#include <iostream>
#include <vector>
#include <climits>
#include <cstdint>
#include <type_traits>
#include <utility>
template<typename ...Args>
void printer(Args&&... args) {
(std::cout << ... << args) << '\n';
}
template<typename T, typename... Args>
void push_back_vec(std::vector<T>& v, Args&&... args)
{
(v.push_back(args), ...
}
// compile-time endianness swap based on http://stackoverflow.com/a/36937049
template<class T, std::size_t... N>
constexpr T bswap_impl(T i, std::index_sequence<N...>) {
return (((i >> N*CHAR_BIT & std::uint8_t(-1)) << (sizeof(T)-1-N)*CHAR_BIT) | ...
}
template<class T, class U = std::make_unsigned_t<T>>
constexpr U bswap(T i) {
return bswap_impl<U>(i, std::make_index_sequence<sizeof(T)>{}
}
int main()
{
printer(1, 2, 3, "abc"
std::vector<int> v;
push_back_vec(v, 6, 2, 45, 12
push_back_vec(v, 1, 2, 9
for (int i : v) std::cout << i << ' ';
static_assert(bswap<std::uint16_t>(0x1234u)==0x3412u
static_assert(bswap<std::uint64_t>(0x0123456789abcdefULL)==0xefcdab8967452301ULL
}
二次
产出:
二次
123abc
6 2 45 12 1 2 9
二次
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。