C++17语法之折叠表达式

256 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 13 天,点击查看活动详情

折叠表达式是C++17引入的一种表达式,用于简化使用可变参数模板时的代码。在使用折叠表达式时,需要编译器支持C++17标准。折叠表达式使用一种特殊的语法,将参数包展开并进行运算。

一、语法

折叠表达式语法如下:

( pack op ... )
( ... op pack )
( init op ... op pack )
( pack op ... op init )

其中,op是一个可折叠二元操作符,pack是一个参数包,init是一个初始值。

1.1 (pack op ...)

pack中的所有元素,使用op操作符连接起来,左右两端可以使用(...)表示逆序展开。

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

int main() {
    std::cout << sum(1, 2, 3, 4, 5) << '\n';  // 输出15
    return 0;
}

这里用逗号分隔的方式展开参数列表,然后对它们进行 + 运算操作。即,用(args + ...)计算参数包args中的所有元素的总和。

1.2 ( ... op pack)

pack中的所有元素,使用op操作符连接起来,左端必须使用(...)表示逆序展开。

template<typename... Args>
void print(Args... args) {
    (std::cout << ... << args) << '\n';
}

int main() {
    print("Hello", " ", "World");  // 输出Hello World
    return 0;
}

这里用逗号分隔的方式展开参数列表,然后将运算操作 << 插入到它们之间。即,用(std::cout << ... << args)将参数包 args 中的所有元素插入到输出流中。

1.3 (init op ... op pack)

initpack中的所有元素,使用op操作符连接起来,左端必须使用括号括起来,右端可以使用(...)表示逆序展开。

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

int main() {
    std::cout << sum(1, 2, 3, 4, 5) << '\n';  // 输出25
    return 0;
}

这里用逗号分隔的方式展开参数列表,然后插入一个初始值,并对它们进行 + 运算操作。即,可以用(10 + ... + args)计算参数包args中的所有元素的总和并加上10。

1.4 (pack op ... op init)

pack中的所有元素和init,使用op操作符连接起来,左端可以使用(...)表示逆序展开,右端必须使用括号括起来。

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

int main() {
    std::cout << sum(1, 2, 3, 4, 5) << '\n';  // 输出40
    return 0;
}

这里用逗号分隔的方式展开参数列表,然后对它们进行 + 运算操作,并在最后插入一个初始值。即,用(args + ... + 10)计算参数包args中的所有元素的总和并加上10。

二、对比概览

( pack op ... )(std::cout << ... << args)
( ... op pack )(std::cout << ... << args)
( init op ... op pack )(10 + ... + args)
( pack op ... op init )(args + ... + 10)