C++函数式编程代码片段
C++ functional programming code snippets
我一直在做一个名为:C++11/14的函数式编程特性的项目(我在大学的一门课)。关于这些主题,有几个现有的来源和类似的演示,我找到了一个不久前,它包含了几个我还没有完全理解的代码片段(不知何故,它们可以与函数式编程联系起来)。代码段A和B属于递归,而C则属于lazy求值。我想在下面与大家分享:
代码段A:
#include <iostream>
template <int N>
struct Factorial {
static int const val = N * Factorial<N - 1>::val;
};
template <>
struct Factorial <0> {
static int const val = 1;
};
int main() {
int factorial_of_6 = Factorial<6>::val;
std::cout << factorial_of_6 << std::endl;
return 0;
}
这里的重点是编译时评估(为了避免运行时计算并提高性能)吗?或者还有其他优势吗?
代码段B:
#include <iostream>
template <int ...>
struct my_sum;
template <>
struct my_sum <> {
static const int value {0};
};
template <int i, int ... tail>
struct my_sum <i, tail ...> {
static const int value = i + my_sum<tail ...>::value;
};
int main() {
int sum {my_sum<1, 2, 3, 4, 5>::value};
std::cout << sum << std::endl;
return 0;
}
上述问题同样适用。
这是另一个可能类似的片段:
代码段C:
#include <iostream>
template <typename... Args>
void some_function (Args ...) {
std::cout << sizeof...(Args) << std::endl;
}
int main() {
some_function ("Every little thing gonna be alright...", 1.0 / 0.0);
return 0;
}
"演示中说:C++很渴望,但以下内容会起作用。"这是不是意味着,在我不在乎给定的表达式之前,我可以说出它们的数量?
请尽可能具体和详细,并非常感谢您的耐心和提前提供的帮助。:)
代码段A
这被称为Template Metaprogramming
,它基本上是一种在编译时使用模板生成代码的技术。这提高了运行时性能,因为计算不是在运行时完成的,而是在编译时完成的。
代码段A在编译时计算给定数字的阶乘:
template <int N>
struct Factorial {
static int const val = N * Factorial<N - 1>::val;
};
这将struct
Factorial
定义为采用int
的模板。在那个struct
中,有一个static const
变量。变量是static
,因此您不必创建Factorial
的实例来访问它,只需使用Factorial::val
而不是
Factorial factorial;
factorial.val;
变量是const
,因为给定数字的阶乘总是相同的,而且如果不是const
,项目就不会编译,因为编译器无法知道你是否在其他地方更改了变量。
变量的值为N * Factorial<N - 1::val;
,基本上将N
与前一个数的阶乘相乘。这是因为阶乘是如何定义的(3! = 2! * 3 = 1! * 2 * 3 = 1 * 2 * 3 = 6
)。
template <>
struct Factorial <0> {
static int const val = 1;
};
这为N = 0
定义了一个完全专用的struct
。这一点非常重要,否则上一个函数中使用的递归将永远不会停止。
那么,得到一个数N
的阶乘就很容易了,Factorial<N>::val
。这将在编译时进行计算。
代码段b
这也是Template Metaprogramming
。
template <int ...>
struct my_sum;
这定义了一个空模板struct
,它采用int...
(一个Parameter Pack
),这样它就可以被专门化(见下一点)。
template <>
struct my_sum <> {
static const int value {0};
};
当没有给定模板参数时,这专门用于struct
my_sum
(这是因为Parameter Pack
可能是空的,因此当Parameter Pack
展开时,模板参数将是空的)。由于与之前相同的原因,value
是static
和const
,并且它是使用initializer list
初始化的0
(对于int
,int i = 0;
和int i{ 0 };
之间没有区别)。
template <int i, int ... tail>
struct my_sum <i, tail ...> {
static const int value = i + my_sum<tail ...>::value;
};
这将struct
my_sum
定义为一个模板,它包含两个模板参数,一个int
和一个int
参数包。这用于获取参数包的第一个值的值,因为不能对参数包(它不是数组)进行索引。然后,value
被初始化为i
(包的第一个值)加上其他值的value
作为参数包,该参数包被扩展(使用...
):
int sum = my_sum<1, 2, 3>::value;
这调用my_sum<int i, int... tail>
,i
是1
,tail
是2, 3
。value
是i + my_sum<tail...>::value
,所以它是1 + my_sum<2, 3>
。my_sum<2, 3>
再次调用相同的函数2 + my_sum<3>::value
。现在我们有了1 + 2 + my_sum<3>::value
。my_sum<3>::value
再次调用相同的函数,但现在参数包为空!所以value
就是1 + 2 + 3 + my_sum<>::value
。CCD_ 57是CCD_ 58(如所定义的),因此CCD_。
代码段C
表达式被求值,但程序不会崩溃,因为求值时的表达式是double
。只有当表达式是int
时,它才会与Integer division by zero exception
崩溃。如果你要这样做:
int zero = 0;
double d = 1.0 / zero;
那么CCD_ 63将具有值CCD_。
函数some_function
是以参数包作为模板参数的模板函数。然后它调用对参数包中的元素进行计数的sizeof...
,并使用std::cout
将其输出。
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- 这两个代码片段相似,但显示的结果不同
- 如何替换此示例代码片段中已弃用的handler_type_t或 boost::asio::handler_type?
- 如果我在下面的代码片段中添加"delete[] d;",为什么我得到零?
- 我遇到了这个代码片段,不明白. 它递归检查 C++ 字符串中是否存在大写字符
- 任何人都可以解释一下我是否需要 & 在第一个代码片段中
- 提取狮身人面像文档中的C++代码片段
- 为什么此代码片段有效?如何取消引用空点?
- 无法在这个基本的Qt代码片段中找到错误,但我被告知它肯定存在?
- 这个代码片段中会发生死锁吗?为什么
- 这个代码片段中的while循环是如何工作的
- 在给定的代码中,有人可以解释一下(int i = 0; i<len; i++)count[str[i]]++的代码片段;
- 为什么我的C++代码在以下打印链表的代码片段中显示分段错误?
- 为什么这两个代码片段具有相同的效果?
- 以下代码片段的时间复杂度是多少?
- 为什么以下代码片段存在编译错误
- 如何在此代码片段中创建 begin() 指针
- 为什么这个简短的模板代码片段有效
- 为什么这个代码片段在 C 和 C++ 中生成完全不同的汇编代码?
- 我应该修复这个晦涩而优雅的C 代码片段吗?