Search code examples
c++templatestype-deduction

When using templates, is it possible to determine the type of Lvalue?


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.


Solution

  • 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.)