锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++开源社区 / C++17折叠表达式用途和改进建议

服务方向

人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
量化预测
股票离线分析软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发

联系方式

固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

锐英源精品原创,禁止转载和任何形式的非法内容使用,违者必究。点名“简易百科”和“闲暇巴”盗用锐英源原创内容。


C++17折叠表达式用途和改进建议


C++17折叠表达式简化了循环计算多个值或变量处理,...代表了N个值或变量,让循环计算简单且易懂,让算法开发更简单,特别是矩阵的行列数据数据计算。改进建议是能支持数组或容器内项的计算,让数组和容器内的项自动进行计算,这样更强大。

以前看过Python的数据结构处理,非常方便,虽然希望C++能够学习,不过也要看现实,毕竟数据结构类型越大,编译器就越麻烦,这和C++性能第一的目标有些相背。

C++17 标准引入了语言语法的一个新元素 - 折叠表达式。这种新语法用于折叠可变参数模板参数包(可变参数模板获取可变数量的参数,自 C++11 起受 C++ 支持)。使用 folding 有助于避免繁琐的递归调用,并允许我们以紧凑的形式将操作应用于 pack 的所有单个参数。在处理模板参数包列表时,折叠表达式可以与以下二元运算符一起使用:+、-、*、/、%、^、&、|、=、<、>、<<、>>、+=、-=、*=、/=、%=、^=、&=、|=、<<=、>>=、==、!=、<=、>=、&&、||、,, .*、->*。

使用可变参数模板声明 fold 表达式的语法:


template<class... T>
decltype(auto) summation(T... Values)
{
// unfolds into the expression Values1 + (Values2 + (Values3 + Values4))...
return (Values + ...);
}
让我们看一下以下示例:


#include <iostream>
#include <string>

template <typename ... Ts>
auto Sum_RightHand(Ts ... ts)
{
return (ts + ...);
}

template <typename ... Ts>
auto Sum_LeftHand(Ts ... ts)
{
return (... + ts);
}

int main() {

std::cout << "Sum_RightHand output: \n";
std::cout << Sum_RightHand(10, 20, 30) << std::endl;
std::cout << Sum_RightHand(1.5, 2.8, 3.2) << std::endl;
std::cout << Sum_RightHand(std::string("Hi "), std::string("standard "),
std::string("C++ 17")) << std::endl;

std::cout << "\n";

std::cout << "Sum_LeftHand output: \n";
std::cout << Sum_LeftHand(10, 20, 30) << std::endl;
std::cout << Sum_LeftHand(1.5, 2.8, 3.2) << std::endl;
std::cout << Sum_LeftHand(std::string("Hi "), std::string("standard "),
std::string("C++ 17")) << std::endl;

return 0;
}

在上面的代码中,对于这两个函数,我们使用模板参数 pack 定义了签名:

模板 <typename ...Ts>
auto function_name (Ts ...ts)

函数展开所有参数并使用 fold 表达式对它们进行汇总。(在函数范围内,我们使用 +运算符应用于参数包的所有值)

正如我们所看到的,Sum_RightHand (ts + ...)和Sum_LeftHand (... + ts)给出相同的结果。但是,它们之间存在差异,这在其他情况下可能很重要:如果省略号 (...) 位于运算符的右侧,则表达式称为右折叠。如果它在左侧,则它是左侧折叠。

在我们的示例中, 展开如下:Sum_LeftHand

10 + (20 + 30)

1.5 + (2.8 + 3.2)

"嗨" + ("标准 " + "C++ 17")

右一元折叠 with 展开如下:Sum_RightHand

(10 +20) + 30

(1.5 + 2.8) + 3.2

("Hi" + "standard ") + "C++ 17"

这些函数适用于不同的数据类型:int 、double 、 和std::string ,但可以为实现 +运算符的任何类型的函数调用它们。

在上面的例子中,我们向两个函数传递了一些参数来获得求和的结果。但是,如果我们调用没有参数的函数会发生什么呢?

例如,如下所示:

C++
int main() {

std::cout << Sum_RightHand() << std::endl;
return 0;
}

Sum_RightHand ()函数调用时不带参数的,任意长度的参数包将不包含可以折叠的值,这会导致编译错误。

要解决这个问题,我们需要返回一个特定的值。一个明显的解决方案是返回零。

所以我们可以像这样实现它:

C++
#include <iostream>
#include <string>

template <typename ... Ts>
auto Sum_RightHand(Ts ... ts) {
return (ts + ... + 0);
}

template <typename ... Ts>
auto Sum_LeftHand(Ts ... ts) {
return (0 + ... + ts);
}

int main() {
std::cout << "Sum_LeftHand() = " << Sum_LeftHand() << std::endl;
std::cout << "Sum_RightHand() = " << Sum_RightHand() << std::endl;
return 0;
}

 

请注意,这两个 fold 表达式都使用初始值 ZERO!当没有参数时,中性元素非常重要 - 在我们的例子中,将任何数字添加到 0 都不会改变任何内容,使 0 成为中性元素。因此,我们可以使用+ or -运算符添加0到任何折叠表达式中。如果参数 pack 为空,这将导致函数返回值0 。从数学的角度来看,这是正确的,但在实现方面,我们需要根据我们的要求确定什么是正确的。

友情链接
版权所有 Copyright(c)2004-2024 锐英源软件
统一社会信用代码:91410105098562502G 豫ICP备08007559号 最佳分辨率 1440*900
地址:郑州市金水区文化路97号郑州大学北区院内南门附近