After getting help from other answers and comments, and reading GCC source code and C++11 standard, I found that it is possible to parse a function type (its return type and its argument types) by using partial template specialization and 
function overloading.
The following is a simple (and incomplete) example to implement something like std::function:
template<class T> class Function { };
// Parse the function type
template<class Res, class Obj, class... ArgTypes>
class Function<Res (Obj*, ArgTypes...)> {
    union Pointers {
        Res (*func)(Obj*, ArgTypes...);
        Res (Obj::*mem_func)(ArgTypes...);
    };
    typedef Res Callback(Pointers&, Obj&, ArgTypes...);
    Pointers ptrs;
    Callback* callback;
    static Res call_func(Pointers& ptrs, Obj& obj, ArgTypes... args) {
        return (*ptrs.func)(&obj, args...);
    }
    static Res call_mem_func(Pointers& ptrs, Obj& obj, ArgTypes... args) {
        return (obj.*(ptrs.mem_func))(args...);
    }
  public:
    Function() : callback(0) { }
    // Parse the function type
    Function(Res (*func)(Obj*, ArgTypes...)) {
        ptrs.func = func;
        callback = &call_func;
    }
    // Parse the function type
    Function(Res (Obj::*mem_func)(ArgTypes...)) {
        ptrs.mem_func = mem_func;
        callback = &call_mem_func;
    }
    Function(const Function& function) {
        ptrs = function.ptrs;
        callback = function.callback;
    }
    Function& operator=(const Function& function) {
        ptrs = function.ptrs;
        callback = function.callback;
        return *this;
    }
    Res operator()(Obj& obj, ArgTypes... args) {
        if(callback == 0) throw 0; // throw an exception
        return (*callback)(ptrs, obj, args...);
    }
};
Usage:
#include <iostream>
struct Funny {
    void print(int i) {
        std::cout << "void (Funny::*)(int): " << i << std::endl;
    }
};
void print(Funny* funny, int i) {
    std::cout << "void (*)(Funny*, int): " << i << std::endl;
}
int main(int argc, char** argv) {
    Funny funny;
    Function<void(Funny*, int)> wmw;
    wmw = &Funny::print; // void (Funny::*)(int)
    wmw(funny, 10); // void (Funny::*)(int)
    wmw = &print; // void (*)(Funny*, int)
    wmw(funny, 8); // void (*)(Funny*, int)
    return 0;
}