Overload a pointer to an overloaded function
If I try to define a pointer to an overloaded function
void myprint(int );
void myprint(const char* );
void (*funpointer)(int) = myprint;
the compiler understands that funpointer
should point to the version of myprint
that matches its arguments. Instead, I want funpointer
to be overloaded as well.
void myprint(int );
void myprint(const char* );
void (*funpointer)(int);
void (*funpointer)(const char *);
void funpointer = myprint;
but then the compiler complains of conflicting declarations for funpointer
(obviously).
Is there a way to achieve what I'm looking for? I would like the pointer to behave as an overloaded function. So I could call it as either funpointer(1)
or funpointer("Hey.")
and it开发者_如何学Python would work as the respective version of myprint
.
Why are you doing this? Function pointers are for runtime polymorphism based on application state. Plain old overloads work fine if, the only variance is the argument type.
If you want to be able to, say write a library that will call overloads defined later, in client code, do something like the following:
void foo(int x) { printf("int\n");}
void foo(const char* c){ printf("char*\n"); }
template <class T> void callfoo(T t) { foo(t); }
int main(int argc, char* argv[])
{
int x = 3;
callfoo(x);
const char* p = "Hello world";
callfoo(p);
return 0;
}
This allows the lib to call overloads for types it is not actually aware of until link time.
No can do. You can't have two variables in the same scope with the same name.
Pointer is a Type, it cannot be overloaded. Only functions can be overloaded.
There is no way to achieve overloading of a pointer in C++.
You can't do it with function pointers... the argument list is part of the type, so any given function pointer can only correspond to one specific overload at a time. You might be able to fake it with function objects, though, depending on what you need to do.
struct MyPrint {
void operator()(int i) { int_f(i); }
void operator()(const char* c_str) { str_f(c_str); }
std::function<void(int)> int_f;
std::function<void(const char*) str_f;
};
void print_int(int i) { cout << i << endl; }
void print_string(const char* str) { cout << str << endl; }
int main() {
MyPrint p;
p.int_f = print_int;
p.str_f = print_string;
p(5);
p("Hi");
}
You lose the ability to just overload by name; you can't add a set_functions(f)
that takes a function name and extracts both versions of the function. But as I showed, now you aren't limited to functions with the same name, or even just to functions. The object is also bigger than it used to be, and likely involves some heap allocations.
This might be considered "clunky", but you could do something like the following:
template<typename T>
struct funcptr_struct
{
typedef T type;
static type ptr;
};
template<> funcptr_struct<void(*)(int)>::type funcptr_struct<void(*)(int)>::ptr = myprint;
template<> funcptr_struct<void(*)(const char*)>::type funcptr_struct<void(*)(const char*)>::ptr = myprint;
You can then call each version of the myprint
function using syntax like the following:
funcptr_struct<void(*)(int)>::ptr(5);
精彩评论