我正在尝试使用模板元编程来确定基类。有没有一种方法可以自动获取基类而无需显式特化每个派生类?
class foo { public: char * Name() { return "foo"; }; };
class bar : public foo { public: char * Name() { return "bar"; }; };
template< typename T > struct ClassInfo { typedef T Base; };
template<> struct ClassInfo<bar> { typedef foo Base; };
int main()
{
ClassInfo<foo>::Base A;
ClassInfo<bar>::Base B;
std::cout << A.Name(); //foo
std::cout << B.Name(); //foo
}
目前任何自动方法都需要选择第一个声明的基地,并且对于私有(private)基地将失败。
最佳答案
使用 C++11 和 decltype
是可能的。为此,当成员从基类继承时,我们将利用指向成员的指针不是指向派生类的指针。
例如:
struct base{
void f(){}
};
struct derived : base{};
&derived::f
的类型将是 void (base::*)()
,而不是 void (derived::*)()
。这在 C++03 中已经成立,但如果不实际指定它,就不可能获得基类类型。使用decltype
,很简单,只需要这个小函数:
// unimplemented to make sure it's only used
// in unevaluated contexts (sizeof, decltype, alignof)
template<class T, class U>
T base_of(U T::*);
用法:
#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();
}
输出:
base::name()
base::name()
not_deducible::name()
如最后一个示例所示,您需要使用的成员实际上是您感兴趣的基类的继承成员。
但是还有更多缺陷:该成员还必须明确标识一个基类成员:
struct base2{ void f(){} };
struct not_deducible2 : base, base2{};
int main(){
decltype(base_of(¬_deducible2::f)) x; // error: 'f' is ambiguous
}
虽然没有编译器支持,但这是您可以获得的最好结果。
关于c++ - 可以从模板类型中自动获取基类的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8709340/