可以在C中创建一个可以自己调用的真正的函数类型吗?

前端之家收集整理的这篇文章主要介绍了可以在C中创建一个可以自己调用的真正的函数类型吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图通过Y-combinator在C中引用函数名来写递归.但是,我无法在以下尝试中找出函数的类型:
  1. #include <iostream>
  2.  
  3. using std::cin;
  4. using std::cout;
  5.  
  6. template<class Function> unsigned long factorial1(Function self,unsigned long n) {
  7. return n ? n * self(self,n - 1) : 1;
  8. }
  9.  
  10. unsigned long factorial(unsigned long n) {
  11. return factorial1(factorial1,n);
  12. }
  13.  
  14. int main() {
  15. unsigned long n;
  16. cin >> n;
  17. cout << factorial(n) << '\n';
  18. return 0;
  19. }

编译器不能推断什么是功能,我也不能.然后我尝试了以下:

  1. #include <iostream>
  2.  
  3. using std::cin;
  4. using std::cout;
  5.  
  6. struct Factorial {
  7. template<class Function> unsigned long operator()(Function self,unsigned long n) const {
  8. return n ? n * self(self,n - 1) : 1;
  9. }
  10. };
  11.  
  12. unsigned long factorial(unsigned long n) {
  13. return Factorial()(Factorial(),n);
  14. }
  15.  
  16. int main() {
  17. unsigned long n;
  18. cin >> n;
  19. cout << factorial(n) << '\n';
  20. return 0;
  21. }

这与上面的例子相比,我将工作函数改为可调用对象,这个函数容易被推导为Factorial,导致以下组合器的完整实现:

  1. #include <iostream>
  2.  
  3. using std::cin;
  4. using std::cout;
  5.  
  6. struct Factorial {
  7. template<class Function> unsigned long operator()(Function self,n - 1) : 1;
  8. }
  9. };
  10.  
  11. template<class Function> auto y(Function f) {
  12. return [f](auto n) {
  13. return f(f,n);
  14. };
  15. }
  16.  
  17. int main() {
  18. unsigned long n;
  19. cin >> n;
  20. cout << y(Factorial())(n) << '\n';
  21. return 0;
  22. }

问题是,是否可以将struct Factorial重写为一个简单的函数

解决方法

你这样做稍微有些错误:factorial1的第一个参数应该是具有类型unsigned long(*)(unsigned long)的factorial1的固定点,而不是factorial1本身,因此不需要为自己提供自己的参数:
  1. unsigned long factorial1(unsigned long(*self)(unsigned long),unsigned long n) {
  2. return n ? n * self(n - 1) : 1;
  3. }

C不允许作为函数指针传递闭包,所以我们必须:

>传递std ::函数或其他一些包装器作为自我.不太有意思的海事组织
>使用模板魔术在编译时生成固定点函数.

第二个选择可以轻松完成:

  1. template<class X,X(*Fn)(X(*)(X),X)>
  2. struct Fix {
  3. static X Function(X x) {
  4. return Fn(Fix<X,Fn>::Function,x);
  5. }
  6. };

现在,Fix< unsigned long,factorial1> :: Function is a fixed point of factorial1

  1. unsigned long factorial(unsigned long n) {
  2. return Fix<unsigned long,factorial1>::Function(n);
  3. };

请注意,此修复实现仍以名称引用,所以任何实现固定点组合器都不会有类型的系统黑客.

猜你在找的C&C++相关文章