The following c开发者_如何学Goode does not compile..but is there some way to get a function pointer to return another function pointer that is equivalent to itself?
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);
}
Short answer: No, you cannot do this directly. You can get close by using void pointers, but it's nonstandard as a void pointer is not guaranteed to be large enough to fit a function pointer. See Guru of the Week #57 for details.
The closest standards-compatible approach is to define a wrapper type for the function pointer:
struct Wrapper;
typedef Wrapper (*FunctionPtr)(int, int);
struct Wrapper {
Wrapper(FunctionPtr ptr): wrapped(ptr) { }
operator FunctionPtr() { return wrapped; }
FunctionPtr wrapped;
};
Now you can write:
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);
}
There's a few clever C++ solutions here, but the pure C solution I've always seen is to just use a little casting:
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);
The standard requires that a function pointer that is cast to another function pointer type and back is equal to the original function pointer, making this code completely reliable.
This was the closest I got to in about 15 minutes...:
#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;
}
Now to make this baby generic for N parameters is left as an exercise to the reader :)
It's not possible because of type checking. It would require compilers to solve fixed points in their type checking, and currently the compilers cannot do it.
The nearest what you can do is abstract away the return type via inheritance:
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);
}
精彩评论