使用模板时,是否可以确定左值的类型?

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

用语言表达有点困难,所以这里举个例子:

int (*foo)(int) = load_sym<decltype(foo)>("foo");

template <typename T>
T load_sym(char *sym) {
    /* some other stuff */
    return (T)dlsym(sym);
}

如果可能的话,我想省略 decltype(foo) 部分以使其简洁。问题是,我可以确定 T 而不必将其显式指定为模板参数吗?

直觉这可能是不可能的,但我很想知道是否有人想出变通办法。

这个怎么样?

auto foo = load_sym<int (*)(int)>("foo");

这是一个避免auto并适用于非静态数据成员的解决方案,但有点难看。

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);
}

现在你可以做

int (*foo)(int) = load_sym("foo");

Symbolclass简单的存储了load_sym的return值,但是提供了一个转换运算符模板,可以用来转换void*指向任何类型的指针。

(请注意,有条件地支持将 void* 转换为函数指针类型,但我相信 POSIX 需要它。)