decltype for overloaded member function [duplicate]

点点圈 提交于 2019-12-30 08:12:27

问题


I have this code:

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

    void other();
};

I can call

decltype(&Foo::other)

but calling

decltype(&Foo::print)

end with error, which is clear to me.

But how can I specify more "closely" which of the four print methods, I want to resolve to decltype?

I want to further use this in

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)>();
....

回答1:


More "closely", as far as I understand, means you want to specify the function arguments of print. That is, for example, you select int, int, then get back the result-type of Foo{}.print(int{},int{}), and thereafter construct a function pointer from all the available information.

Here is an alias template which does that for you in a general way:

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

You could also use std::result_of instead of the std::declval stuff, but I like the latter more.

You can use the above as

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

EDIT: as asked for by @JavaLover, which btw seems like an unsuitable name for such horrible C++ shit :-), here is the same as above using std::result_of (untested now tested and wrong):

//------ 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 --------

You could further abstract away the Foo but not the print (unless you're using macros).




回答2:


Not sure about the exact syntax but, in case of method name overloading, you should cast the pointer; something like

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

In you're interested only in type, should be the template value of the cast

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


来源:https://stackoverflow.com/questions/40135561/decltype-for-overloaded-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!