aha*_*ala 11 c++ templates functional-programming
是c ++模板元编程是一种函数式编程吗?如果是的话,为c ++模板元编程相关的非尾递归做一些像stackoverflow这样的陷阱吗?
对于这个问题中的阶乘模板示例,我想这是标准的函数式编程.或者相似性只是肤浅的?
#include <iostream>
using namespace std;
template< int n >
struct factorial { enum { ret = factorial< n - 1 >::ret * n }; };
template<>
struct factorial< 0 > { enum { ret = 1 }; };
int main() {
cout << "7! = " << factorial< 7 >::ret << endl; // 5040
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是c ++模板元编程是一种函数式编程吗?
是的!模板扩展没有副作用,因此它是纯功能的.
如果是的话,为c ++模板元编程相关的非尾递归做一些像stackoverflow这样的陷阱吗?
绝对.Factorial不是一个很好的证明,因为结果会在堆栈运行之前很久就会溢出,但是长递归肯定会导致编译器出错.然而,有趣的是,编译器倾向于以这样的方式实现模板,以便您获得自动memoization.例如,Fibonacci系列的天真编写实现将倾向于在O(n)时间而不是O(2 ^ n)编译.
我认为最好的答案是这两个概念完全不同.但是,这并没有什么帮助,所以这里有一些我能想到的关键点:
像ML这样的函数式语言中的C++模板和(参数多态)都是泛型编程的例子,因此在一个问题中一起提及它们是有意义的.在学术界,甚至还有通用编程研讨会,它通常涵盖C++模板和ML风格的函数式编程.
但是,模板元编程为您提供了一种编写在编译C++代码期间"评估"的代码的方法,因此您只能将它用于非常有限的任务.另一方面,功能程序通常在运行时运行,您可以定义复杂的数据结构,构建抽象等(您可以使用模板元编程来做一些事情,但它看起来很难看).
为什么阶乘示例类似于函数式编程中的阶乘?当您使用模板元编程时,您无法定义"可变变量"(因为您只是定义新类型或模板),因此模板元编程可能会感觉有点像函数式编程风格.
使用模板元编程编写的代码在编译时进行评估.这意味着它不能依赖于用户输入!它是编译与否(编译器可能对递归的深度有一些限制,并在一段时间后放弃).另一方面,功能程序可以接受一些输入然后进行评估(这意味着它们可以使用所有可用的堆栈或内存然后失败).
对于函数式程序员,我知道像Agda这样的函数式语言也可以在编译时对事物进行评估,但我认为最好保持简单!