2010-12-17 114 views
3

我有一个模板函数接受对象。我需要确定对象是否来自特定的基类。如果它是从基类派生的,我需要调用附加函数。无论如何,我可以在C++ Linux中做到这一点?模板类型检查C++

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

不知道你想要做的额外工作的确切性质,可能有两种方法可以实现这一点。选择1: 说你想调用的函数是foo()。你可以在baseA和testB上实现foo()。 baseA :: foo()可以为你提供额外的工作,而testB:foo()将不会做任何事情。但是如果foo()不属于这两个类中的任何一个,这种风格就没有意义了。

可选2: 专营泛函的baseA(或可选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) 
{ 
    //... 
} 
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; 
} 
+1

这个“工作”,但并不是最佳的,因为有一个编译时间的解决方案 – 2010-12-17 18:29:29

+0

你不需要删除'B'吗? – Xocoatzin 2013-12-12 15:52:22

-1

你可以做模板特殊化,这将是完全静态的:

template <typename T> 
void function(const T& value) 
{ 
    common_task(); 
} 

template <> 
void function<A>(const A& value) 
{ 
    common_task(); 
    // special A tasks 
} 
+1

真的吗?问题是关于使用'B b; foo(b);'struct where B:A {};',在你的情况下,我高度怀疑泛型版本会被调用。 – 2010-12-17 07:34:53

+0

确切的说,我认为是相反的:B <:A – 2010-12-17 21:16:40

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()); 
} 
+2

真的吗?问题是关于使用'B b; foo(b);'struct where B:A {};',在你的情况下,我高度怀疑泛型版本会被调用。 – 2010-12-17 07:34:28

+0

你是对的,我的代码只适用于A类...模板专业化不适用于派生类A. 对不起! – MatiasFG 2011-01-11 16:11:52

2

混合模板和继承有点困难。

麻烦:

template <typename T> 
void function(T const& t); 

void function(A const& a); 

如果使用struct B: A {}:,然后模板版本是首选,因为不需要转换,因此,它是一个“更好”的比赛。

如果您有权访问模板版本的定义,则可以使用is_base_ofdisable_if的组合。

template <typename T> 
typename boost::disable_if< boost::is_base_of<A, T> >::type function(T const& t); 

这种简单的修改利用SFINAE,基本上它生成试图实例functionA和C++标准派生的任何类时的错误指定如果功能可以不被实例化,然后它要被去除来自所考虑的一组重载而不触发编译器错误。

如果您无法访问function的模板定义,那么您运气不好。

+0

是不是应该是'boost :: is_base_of :: value'? – refi64 2014-03-07 15:11:58

+0

'boost :: disable_if','boost :: disable_if_c'和'std :: enable_if'之间有区别。前者期望一个名为'type'的嵌套类型,其内部'value'成员应该是'true'或'false',而后者期望直接'bool'。所以,通常这个答案是正确的。在'std'方面它将是'template 使用disable_if = std :: enable_if ;''和'typename std :: disable_if :: value> ::输入' – 2014-03-07 15:16:14

+0

Ack,你说得对,我在考虑'enable_if'。 – refi64 2014-03-07 15:19:17