【发布时间】:2017-04-01 07:39:32
【问题描述】:
我正在尝试编写递归而不通过 Y-combinator 在 C++ 中引用函数名。但是,在以下尝试中我无法确定函数的类型:
#include <iostream>
using std::cin;
using std::cout;
template<class Function> unsigned long factorial1(Function self, unsigned long n) {
return n ? n * self(self, n - 1) : 1;
}
unsigned long factorial(unsigned long n) {
return factorial1(factorial1, n);
}
int main() {
unsigned long n;
cin >> n;
cout << factorial(n) << '\n';
return 0;
}
编译器无法推断出Function 是什么,我也不能。然后我尝试了以下方法:
#include <iostream>
using std::cin;
using std::cout;
struct Factorial {
template<class Function> unsigned long operator()(Function self, unsigned long n) const {
return n ? n * self(self, n - 1) : 1;
}
};
unsigned long factorial(unsigned long n) {
return Factorial()(Factorial(), n);
}
int main() {
unsigned long n;
cin >> n;
cout << factorial(n) << '\n';
return 0;
}
这个,与上面的例子相比,不同的是我把工作函数改成了一个可调用的对象,Function很容易推导出为Factorial,导致下面的组合子的完整实现:
#include <iostream>
using std::cin;
using std::cout;
struct Factorial {
template<class Function> unsigned long operator()(Function self, unsigned long n) const {
return n ? n * self(self, n - 1) : 1;
}
};
template<class Function> auto y(Function f) {
return [f](auto n) {
return f(f, n);
};
}
int main() {
unsigned long n;
cin >> n;
cout << y(Factorial())(n) << '\n';
return 0;
}
问题是,是否可以将结构 Factorial 重写为普通函数?
【问题讨论】:
-
看你的第一个例子:你为什么不想引用函数名?为什么
factorial1是模板?如果不是factorial1,self会是什么? -
Y 组合器需要一个更强大的类型系统(模板提供的,正如您自己发现的,也显示了here at Rosetta Code)或它需要一个不存在 i> 类型系统,如(无类型的)lambda 演算。因此,请尝试使用
std::uintptr_t并在必要时进行强制转换...(顺便说一句:对此评论不提供任何保证。) -
人们用 y 组合器回答了我不相关的问题:stackoverflow.com/questions/42796710/…