Я пытаюсь написать рекурсию без ссылки на имя функции в С++ с помощью Y-combinator. Однако я не могу определить тип функции в следующей попытке:
#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;
}
Вопрос в том, можно ли переписать struct Factorial
на обычную функцию?