简体   繁体   English

模板类型检查C ++

[英]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;

How does `is_base_of` work? `is_base_of`是如何工作的?

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_ofdisable_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM