[英]Template type check C++
I have a template function which takes in objects. 我有一个模板功能,它接收对象。 I need to determine whether the object is derived from a particular base class. 我需要确定对象是否派生自特定的基类。 If it is derived from the base class, I need to call additional function. 如果它是从基类派生的,我需要调用附加函数。 Is there anyway I could do it in C++ Linux? 无论如何我能用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...
}
To clarify, the additional function is a member function in derivedA but not in testB. 为了澄清,附加函数是derivedA中的成员函数,但不是testB中的成员函数。
Boost.TypeTraits boost::is_base_of Boost.TypeTraits boost :: is_base_of
const bool is = boost::is_base_of<Base,Derived>::value;
It is somewhat difficult to mix templates and inheritance. 混合模板和继承有点困难。
The trouble: 麻烦:
template <typename T>
void function(T const& t);
void function(A const& a);
If you use struct B: A {}:
, then the template version is preferred, because no conversion is required, and it is therefore a "better" match. 如果您使用struct B: A {}:
,则首选模板版本,因为不需要转换,因此它是“更好”的匹配。
If you have access to the definition of the template version, you can use a combination of is_base_of
and disable_if
. 如果您可以访问模板版本的定义,则可以使用is_base_of
和disable_if
的组合。
template <typename T>
typename boost::disable_if< boost::is_base_of<A, T> >::type function(T const& t);
This simple modification makes use of SFINAE, basically it generates an error when trying to instantiate function
for any class derived from A
and the C++ standard specifies that if a function may not be instantiated then it is to be removed from the set of overloads considered without triggering a compiler error. 这个简单的修改使用了SFINAE,基本上它在尝试为从A
派生的任何类实例化function
时产生错误,并且C ++标准指定如果某个函数可能没有被实例化,那么它将从没有考虑的重载集中删除触发编译器错误。
If you do not have access to the template definition of function
, you're out of luck. 如果您无法访问function
的模板定义,那么您就不走运了。
You can use Run Time Type Identification (RTTI) for this purpose. 您可以使用运行时类型标识(RTTI)来实现此目的。 An Example follows: 示例如下:
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;
}
Without knowing the exact nature of the additional work you want to do, there could be 2 ways might approach this. 如果不知道您想要做的额外工作的确切性质,可能有两种方法可以解决这个问题。
Option 1: Say the function you want to call is foo(). 选项1:假设您要调用的函数是foo()。 You could implement foo() on both baseA and testB. 您可以在baseA和testB上实现foo()。 baseA::foo() can give you your extra work while testB:foo() would just do nothing. baseA :: foo()可以为你提供额外的工作,而testB:foo()只会做什么。 But this style wouldn't make sense if foo() doesn't belong in either of those 2 classes. 但是如果foo()不属于这两个类中的任何一个,那么这种风格是没有意义的。
Optional 2: Specialize functionA for baseA (or optionally testB as well) 可选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)
{
//...
}
A true template specialization would be even better :) 真正的模板专业化会更好:)
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());
}
You can do template specialization which will be fully static: 您可以进行完全静态的模板专业化:
template <typename T>
void function(const T& value)
{
common_task();
}
template <>
void function<A>(const A& value)
{
common_task();
// special A tasks
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.