如何从指向方法的指针获取 class (对象类型)
How get the class (object type) from pointer to method
我有一个指向方法的指针:
struct A { int method() { return 0; } };
auto fn = &A::method;
我可以通过 std::result_of 获得 return 类型,但是如何从 fn 获得方法的 class 所有者?
试试这个:
template<class T>
struct MethodInfo;
template<class C, class R, class... A>
struct MethodInfo<R(C::*)(A...)> //method pointer
{
typedef C ClassType;
typedef R ReturnType;
typedef std::tuple<A...> ArgsTuple;
};
template<class C, class R, class... A>
struct MethodInfo<R(C::*)(A...) const> : MethodInfo<R(C::*)(A...)> {}; //const method pointer
template<class C, class R, class... A>
struct MethodInfo<R(C::*)(A...) volatile> : MethodInfo<R(C::*)(A...)> {}; //volatile method pointer
您可以使用 class-template-specialization:
来匹配它
//Primary template
template<typename T> struct ClassOf {};
//Thanks T.C for suggesting leaving out the funtion /^argument
template<typename Return, typename Class>
struct ClassOf<Return (Class::*)>{ using type = Class; };
//An alias
template< typename T> using ClassOf_t = typename ClassOf<T>::type;
因此给出:
struct A { int method() { return 0; } };
auto fn = &A::method;
我们可以像这样检索 class:
ClassOf_t<decltype(fn)> a;
完整示例 Here.
Boost callable traits 答案,我更喜欢它而不是这里的简短答案,因为它对我来说更具可读性,但意见可能不同......
#include<string>
#include<type_traits>
#include<tuple>
#include <boost/callable_traits/args.hpp>
struct S{
int val=46;
int get(){
return val;
}
void method(const std::string ){
}
};
int main(){
using Ts1 = boost::callable_traits::args_t<decltype(&S::val)>;
using Ts2 = boost::callable_traits::args_t<decltype(&S::get)>;
using Ts3 = boost::callable_traits::args_t<decltype(&S::method)>;
std::remove_cvref_t<std::tuple_element<0,Ts1>::type> s1;
s1.val++;
std::remove_cvref_t<std::tuple_element<0,Ts2>::type> s2;
s2.val++;
std::remove_cvref_t<std::tuple_element<0,Ts3>::type> s3;
s3.val++;
}
s1
、s2
、s3
都是S型。
显然你只需要执行一次逻辑,我做了 3 次以表明它适用于指向成员的指针、指向采用 0 个参数的函数的指针、采用 1 个参数的函数的指针。
我有一个指向方法的指针:
struct A { int method() { return 0; } };
auto fn = &A::method;
我可以通过 std::result_of 获得 return 类型,但是如何从 fn 获得方法的 class 所有者?
试试这个:
template<class T>
struct MethodInfo;
template<class C, class R, class... A>
struct MethodInfo<R(C::*)(A...)> //method pointer
{
typedef C ClassType;
typedef R ReturnType;
typedef std::tuple<A...> ArgsTuple;
};
template<class C, class R, class... A>
struct MethodInfo<R(C::*)(A...) const> : MethodInfo<R(C::*)(A...)> {}; //const method pointer
template<class C, class R, class... A>
struct MethodInfo<R(C::*)(A...) volatile> : MethodInfo<R(C::*)(A...)> {}; //volatile method pointer
您可以使用 class-template-specialization:
来匹配它//Primary template
template<typename T> struct ClassOf {};
//Thanks T.C for suggesting leaving out the funtion /^argument
template<typename Return, typename Class>
struct ClassOf<Return (Class::*)>{ using type = Class; };
//An alias
template< typename T> using ClassOf_t = typename ClassOf<T>::type;
因此给出:
struct A { int method() { return 0; } };
auto fn = &A::method;
我们可以像这样检索 class:
ClassOf_t<decltype(fn)> a;
完整示例 Here.
Boost callable traits 答案,我更喜欢它而不是这里的简短答案,因为它对我来说更具可读性,但意见可能不同......
#include<string>
#include<type_traits>
#include<tuple>
#include <boost/callable_traits/args.hpp>
struct S{
int val=46;
int get(){
return val;
}
void method(const std::string ){
}
};
int main(){
using Ts1 = boost::callable_traits::args_t<decltype(&S::val)>;
using Ts2 = boost::callable_traits::args_t<decltype(&S::get)>;
using Ts3 = boost::callable_traits::args_t<decltype(&S::method)>;
std::remove_cvref_t<std::tuple_element<0,Ts1>::type> s1;
s1.val++;
std::remove_cvref_t<std::tuple_element<0,Ts2>::type> s2;
s2.val++;
std::remove_cvref_t<std::tuple_element<0,Ts3>::type> s3;
s3.val++;
}
s1
、s2
、s3
都是S型。
显然你只需要执行一次逻辑,我做了 3 次以表明它适用于指向成员的指针、指向采用 0 个参数的函数的指针、采用 1 个参数的函数的指针。