问题
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