It's sort of hard to put it into words, so here's an example instead:
int (*foo)(int) = load_sym<decltype(foo)>("foo");
template <typename T>
T load_sym(char *sym) {
/* some other stuff */
return (T)dlsym(sym);
}
If possible I'd like to omit the decltype(foo)
part to make it succinct. The question is, can I determine T
without having to explicitly specify it as a template argument?
Gut feeling that it's probably not possible, but I'm curious to know if people have come up with work around.
Here's a solution that avoids auto
and works in the case of a non-static data member, but is a bit ugly.
struct Symbol {
Symbol(void* p) : p(p) {}
template <typename T>
operator T*() { return reinterpret_cast<T*>(p); }
void* p;
};
Symbol load_sym(const char *sym) {
/* some other stuff */
return dlsym(sym);
}
Now you can do
int (*foo)(int) = load_sym("foo");
The Symbol
class simply stores the return value of load_sym
, but provides a conversion operator template that can be used to convert the void*
to a pointer of any type.
(Note that conversion of void*
to function pointer type is conditionally supported, but I believe POSIX requires it.)