Es posible con C++ 11 y decltype
. Para eso, explotaremos que un puntero a miembro no es un puntero en la clase derivada cuando el miembro se hereda de una clase base.
Por ejemplo:
struct base{
void f(){}
};
struct derived : base{};
El tipo de &derived::f
será void (base::*)()
, no void (derived::*)()
. Esto ya era cierto en C++ 03, pero era imposible obtener el tipo de clase base sin especificarlo realmente. Con decltype
, es fácil y sólo necesita esta pequeña función:
// unimplemented to make sure it's only used
// in unevaluated contexts (sizeof, decltype, alignof)
template<class T, class U>
T base_of(U T::*);
Uso:
#include <iostream>
// unimplemented to make sure it's only used
// in unevaluated contexts (sizeof, decltype, alignof)
template<class T, class R>
T base_of(R T::*);
struct base{
void f(){}
void name(){ std::cout << "base::name()\n"; }
};
struct derived : base{
void name(){ std::cout << "derived::name()\n"; }
};
struct not_deducible : base{
void f(){}
void name(){ std::cout << "not_deducible::name()\n"; }
};
int main(){
decltype(base_of(&derived::f)) a;
decltype(base_of(&base::f)) b;
decltype(base_of(¬_deducible::f)) c;
a.name();
b.name();
c.name();
}
Salida:
base::name()
base::name()
not_deducible::name()
Como último ejemplo muestra, es necesario utilizar un elemento que se es en realidad un miembro heredado de la clase base en la que está interesado.
The re son más defectos, sin embargo: El miembro también debe identificar de forma inequívoca un miembro de la clase base:
struct base2{ void f(){} };
struct not_deducible2 : base, base2{};
int main(){
decltype(base_of(¬_deducible2::f)) x; // error: 'f' is ambiguous
}
Eso es lo mejor que se puede conseguir, sin embargo, sin el apoyo del compilador.
Utilice ['std :: is_base_of '] (http://stackoverflow.com/questions/2910979/how-is-base-of-works) – iammilind
@iammilind: Eso es solo para probar si una clase es la base de otro, tienes que saber la clase base para probar en contra. – Xeo
¿Para qué lo necesitas? No creo que sea posible, pero tal vez haya un enfoque diferente para resolver el problema real. –