返回功能指向自我的指针?

时间:2011-05-07 19:49:37

标签: c++ function-pointers

以下代码无法编译..但是有没有办法让函数指针返回另一个与自身等效的函数指针?

typedef FunctionPtr (*FunctionPtr)(int, int);

FunctionPtr Second(int, int);
FunctionPtr First(int, int)
{
    // do something
    return Second;
}

FunctionPtr Second(int, int)
{
    // do something
    return First;
}

int main()
{
    FunctionPtr a = First(1, 2);
    FunctionPtr b = a(2, 3);
    FunctionPtr c = b(4, 5);
    c(5, 6);
}

4 个答案:

答案 0 :(得分:5)

简短回答:不,你不能直接这样做。你可以通过使用void指针来接近,但它是非标准的,因为无法保证void指针足够大以适应函数指针。有关详细信息,请参阅Guru of the Week #57

最接近标准兼容的方法是为函数指针定义包装类型:

 struct Wrapper;
 typedef Wrapper (*FunctionPtr)(int, int);
 struct Wrapper {
    Wrapper(FunctionPtr ptr): wrapped(ptr) { }
    operator FunctionPtr() { return wrapped; }
    FunctionPtr wrapped;
 };

现在你可以写:

Wrapper Second(int, int);
Wrapper First(int, int) {
    // do something
    return Second;
}

Wrapper Second(int, int) {
    // do something
    return First;
}

int main() {
    FunctionPtr a = First(1, 2);
    FunctionPtr b = a(2, 3);
    FunctionPtr c = b(4, 5);
    c(5, 6);
}

答案 1 :(得分:2)

这里有一些聪明的C ++解决方案,但我一直看到的纯C解决方案只是使用一点点演员:

typedef void (*func)(void);

func myfunc(int, int) { return (func)myfunc); }
// optional
typedef func (*myfunctype)(int, int);

// calling code
myfunctype x = myfunc;
while(x) x = (myfunctype)x(2, 3);

该标准要求转换为另一个函数指针类型和back 的函数指针等于原始函数指针,使此代码完全可靠。

答案 2 :(得分:1)

这是我在大约15分钟内最接近的......:

#include <stdio.h>

struct container
{
    typedef container (*Ptr)(int, int);
    const Ptr _ptr;
    explicit container(Ptr ptr) : _ptr(ptr) { }
    operator Ptr() const { return _ptr; }
};

struct container narcissus(int a, int b)
{
  printf("Narcissus: %i %i.\n", a, b);

  return container(narcissus);
}

int main(void)
{
  narcissus(3, 4)(5, 6)(7, 8);
  return 0;
}

现在让这个婴儿通用的N参数留给读者练习:)

答案 3 :(得分:0)

由于类型检查,这是不可能的。它需要编译器在类型检查中解决固定点,目前编译器不能这样做。

最接近你可以做的是通过继承抽象返回类型:

template<class T>
class Function { public: virtual void Map(T t)=0; };

template<class T, class K>
class FunctionPtr : public Function<T> {
public:
  FunctionPtr(K (*fptr)(T)) : fptr(fptr) { }
  void Map(T t) { fptr(t); }
private:
  K (*fptr)(T);
};

Function<int> *my_function(int i)
{
   return new FunctionPtr<int,Function<int>*>(&my_function);
}