重载成员函数的解除类型

decltype for overloaded member function

本文关键字:类型 成员 函数 重载      更新时间:2023-10-16

我有这样的代码:

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)

以error结束,这对我来说很清楚。

但是,我如何更"紧密地"指定四个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)>();
....

更"紧密",据我所知,意味着你想指定print的函数参数。也就是说,例如,选择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(除非使用宏)。

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

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

如果您只对类型感兴趣,则应该是强制转换的模板值

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