我有一个模板功能,它接收对象。我需要确定对象是否派生自特定的基类。如果它是从基类派生的,我需要调用附加函数。无论如何我可以在C ++ Linux中做到这一点吗?
class baseA{
};
class derivedA:baseA{
};
class testB{
};
template<typename T>
void functionA(const T& value){
//if T is derived from baseA, call an additional function
//perform common operations for derivedA and testB...
}
为了澄清,附加功能是derivedA中的成员函数,但不是testB中的成员函数。
答案 0 :(得分:3)
Boost.TypeTraits 升压:: is_base_of
const bool is = boost::is_base_of<Base,Derived>::value;
答案 1 :(得分:2)
混合模板和继承有点困难。
麻烦:
template <typename T>
void function(T const& t);
void function(A const& a);
如果您使用struct B: A {}:
,则首选模板版本,因为不需要转换,因此它是“更好”的匹配。
如果您可以访问模板版本的定义,则可以使用is_base_of
和disable_if
的组合。
template <typename T>
typename boost::disable_if< boost::is_base_of<A, T> >::type function(T const& t);
这个简单的修改使用了SFINAE,基本上它在尝试为function
派生的任何类实例化A
时产生错误,并且C ++标准指定如果某个函数可能没有被实例化,那么它将被从被考虑的重载集中删除而不会触发编译器错误。
如果您无法访问function
的模板定义,那么您就不幸了。
答案 2 :(得分:1)
您可以使用运行时类型标识(RTTI)来实现此目的。示例如下:
class A{
public:
virtual void func(){cout << "Base" << endl;}
virtual ~A(){}
};
class B:public A{
public:
void func(){cout << "Derived" << endl;}
};
int main(){
A * d1 = new B();
B * d2;
d1 -> func() ;
d2 = dynamic_cast<B*>(d1);
if(d2 != NULL)
cout << "Base exists" << endl;
else
cout << "No relation" << endl;
return 0;
}
答案 3 :(得分:0)
如果不知道您想要做的额外工作的确切性质,可能有两种方法可以解决这个问题。
选项1: 假设您要调用的函数是foo()。您可以在baseA和testB上实现foo()。 baseA :: foo()可以为你提供额外的工作,而testB:foo()只会做什么。但是如果foo()不属于这两个类中的任何一个,那么这种风格是没有意义的。
可选2: 专门针对baseA的功能A(或者也可选择testB)
void function_specialized(baseA* param)
{
// Do your extra work
// Then call the common functionA
functionA<baseA>(*param);
}
template<typename T>
functionA(const T& value)
{
//...
}
答案 4 :(得分:0)
真正的模板专业化会更好:)
class A {
public:
char c;
};
template <typename T> void foo(const T & t)
{
std::cout << "this is generic.";
}
template <> void foo(const A & a)
{
std::cout << "this is specialized.";
}
int main(int argc, char * argv[])
{
foo(A());
foo(int());
}
答案 5 :(得分:-1)
您可以进行完全静态的模板专业化:
template <typename T>
void function(const T& value)
{
common_task();
}
template <>
void function<A>(const A& value)
{
common_task();
// special A tasks
}