E 'possibile con C++ 11 e decltype
. Per questo, sfrutteremo il fatto che un puntatore-membro non è un puntatore nella classe derivata quando il membro è ereditato da una classe base.
Ad esempio:
struct base{
void f(){}
};
struct derived : base{};
Il tipo di &derived::f
sarà void (base::*)()
, non void (derived::*)()
. Questo era già vero in C++ 03, ma era impossibile ottenere il tipo di classe base senza specificarlo. Con decltype
, è facile e necessita solo di questa piccola funzione:
// unimplemented to make sure it's only used
// in unevaluated contexts (sizeof, decltype, alignof)
template<class T, class U>
T base_of(U T::*);
Usage:
#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();
}
uscita:
base::name()
base::name()
not_deducible::name()
Come ultimo esempio mostra, è necessario utilizzare un membro che è in realtà un membro ereditato della classe di base che ti interessa.
Il re sono più difetti, però: Il membro deve anche essere inequivocabilmente identificare un membro della classe di base:
struct base2{ void f(){} };
struct not_deducible2 : base, base2{};
int main(){
decltype(base_of(¬_deducible2::f)) x; // error: 'f' is ambiguous
}
Questo è il migliore che si può ottenere, però, senza il supporto del compilatore.
Utilizzare ['std :: is_base_of '] (http://stackoverflow.com/questions/2910979/how-is-base-of-works) – iammilind
@iammilind: Questo è solo per testare se una classe è la base di un altro, devi conoscere la classe base per testare già contro. – Xeo
Per cosa ti serve? Non penso sia possibile, ma forse esiste un approccio diverso per risolvere il problema reale. –