2017-02-11 20 views
4

У меня есть указатель на метод:Как получить класс (тип объекта) от указателя на метод

struct A { int method() { return 0; } }; 
auto fn = &A::method; 

я могу получить тип возвращаемого по станд :: result_of, но как я могу получить от Fn владелец класса метода?

+0

Вы не можете, в стандарте нет такой черты. Компилятор знал бы это, поэтому это должно быть возможно, но просто нет способа получить эту информацию. –

+4

template <класс ClassType, класс ReturnType, класс ... Args> ClassType foo (ReturnType (ClassType :: *) (Args ...)); должен работать – felix

+1

@felix Вы должны написать это как ответ. – nwp

ответ

3

Попробуйте это:

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 
+0

Возможно, вам понадобится отдельный 'const volatile'. – HolyBlackCat

+0

Да, вы правы –

2

Вы можете сопрягать его с помощью класса-шаблона специализацию:

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

Мы можем получить класс как :

ClassOf_t<decltype(fn)> a; 

Полный пример Here.

+0

... или просто специализируетесь на 'F C :: *' вместо 48 специализаций для каждого возможного типа функции. –

+0

@ T.C. Я пропустил это. Благодаря!!. Редактирование сейчас – WhiZTiM