重载成员函数的 decltype

decltype for overloaded member function

我有这个代码:

struct Foo 
{
    int print(int a, double b);
    int print(int a);
    void print();
    void print(int a, int b, int c);

    void other();
};

我可以打电话

decltype(&Foo::other)

但是打电话

decltype(&Foo::print)

以错误结束,我很清楚。

但是如何指定更多 "closely" 四个 print 方法中的哪一个,我想解析为 decltype

我想在

中进一步使用它
template <class MT>
struct method_info;

template <class T, class Res, class... Args>
struct method_info<Res(T::*)(Args...)>
{
    typedef std::tuple<Args&&...> args_tuple;
    typedef T ClassType;
    typedef Res RetVal; 
};



template <class MethodType>
void func() {
   typedef method_info<MethodType> MethodInfo;
   .....
}

func<decltype(&Foo::other)>();
....

不确定确切的语法,但是,在方法名称重载的情况下,您应该强制转换指针;像

static_cast<void(Foo::*)(int, int, int)>(&Foo::print);

在你只对类型感兴趣的情况下,应该是强制转换的模板值

void(Foo::*)(int, int, int)

More "closely",据我理解,意思是你要指定print的函数参数。也就是说,例如,您 select int, int,然后取回 Foo{}.print(int{},int{}) 的结果类型,然后根据所有可用信息构造一个函数指针。

这是一个通用的别名模板:

template<typename ... Args>
using ptr_to_print_type = decltype(std::declval<Foo>().print(std::declval<Args>() ...)) (Foo::*)(Args ...);

你也可以用std::result_of代替std::declval,但我更喜欢后者。

你可以把上面的当作

func<ptr_to_print_type<int,int> >();

编辑:正如@JavaLover 所要求的,顺便说一句,对于这种可怕的 C++ 狗屎来说,这似乎是一个不合适的名字:-),这里与上面使用的相同 std::result_of (未测试 现在测试和错误):

//------ does not compile for overloaded functions --------
template<typename ... Args>
using ptr_to_print_type = std::result_of_t<decltype(&Foo::print)(Foo, Args ...)> (Foo::*)(Args ...)
//------ does not compile for overloaded functions --------

您可以进一步抽象掉 Foo 而不是 print(除非您使用宏)。