模板类型检查C ++

时间:2010-12-17 03:39:50

标签: c++

我有一个模板功能,它接收对象。我需要确定对象是否派生自特定的基类。如果它是从基类派生的,我需要调用附加函数。无论如何我可以在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中的成员函数。

6 个答案:

答案 0 :(得分:3)

Boost.TypeTraits 升压:: is_base_of

const bool is = boost::is_base_of<Base,Derived>::value;

How does `is_base_of` work?

答案 1 :(得分: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,基本上它在尝试为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
}