在没有类实例的情况下检查c ++模板中的类

时间:2011-06-27 10:20:32

标签: c++ templates rtti

我需要编写模板,根据模板参数是否为某个类的实例,生成一些代码。可以为所有类生成模板,但仅当该类是其他类的子类时才应该执行代码。

问题是应该实现的函数不接收类的任何实例,因此唯一已知的是类名。所以使用dynamic_cast是不可能的,因为它需要对象的实例

template<T>
class A 
{
  void somefunction(void)
  {
     if (T instanceof Foo) then ...
     else ...
  }
}

添加一些解释

class X: public Foo {};
class Y {};

class A<X> {} // special logic is generated
class A<Y> {} // special logic is NOT generated

5 个答案:

答案 0 :(得分:3)

您可以使用boost traits library中的模板专精或boost :: is_base_of 或者当然要编写自己的特性,但不应该,因为你还没有掌握模板。

使用专业化,你可以

template<T>
class A 
{
  void somefunction() {
     // generic version
  }
};
template<>
class A <Foo>
{
  void somefunction() {
     // foo version
  }
};

与往常一样,让我推荐Vandevoorde / Josuttis“C ++模板:完整指南”。

如果你担心代码膨胀,因为只有一个成员函数需要专门化,你仍然可以外包该函数:

template <typename T> struct somefunction_helper {
    static void thatfunction () {
        // generic form
    }
};
template <> struct somefunction_helper<Foo> {
    static void thatfunction () {
        // Foo form
    }
};

template<T>
class A 
{
  void somefunction()  {
     somefunction_helper<T>::thatfunction();
  }
};

答案 1 :(得分:2)

这是模板专业化的用途。他们写作起来比较困难,但这就是你用它们做的事情。例如:

template<T> class A
{
    void somefunction(void) {
        ...//default for any object type.
    }
};

template<> class A<Foo>
{
    void somefunction(void) {
        ...//specific to the type Foo.
    }
};

是的,这需要额外的工作。有一些模板元编程方法可以按照你想要的方式做到这一点,但其他人必须解释这些。

答案 2 :(得分:1)

要么专门化A,要么将someFunction()成员函数模板的工作委托给一些你可以(完全)专注于T的免费功能模板。

答案 3 :(得分:0)

由于模板参数只能从Foo派生,因此专业化不起作用,请使用另一个答案:is_base_of,来自Boost或来自标准库(如果它已经支持部件) C ++ 0x:

#include <type_traits> // C++0x

class Foo{};

template<class T>
class A{
  void specialOnFoo(){
    // dispatch the call
    specialOnFoo(std::is_base_of<T, Foo>::type());
  }

  void specialOnFoo(std::true_type){
    // handle Foo case
  }

  void specialOnFoo(std::false_type){
    // non-Foo case
  }
};

答案 4 :(得分:-1)

编辑#2 - 参见工作示例。请注意,这是模板特化的运行时等效项(在编译时发生)并且需要启用RTTI。

#include <iostream>
#include <typeinfo>
using namespace std;

class Foo {};
class X: public Foo {};
class Y {};

template<typename T> class A {
public:
  void somefunction()
  {
    if (typeid(T) == typeid(X)) {
      cout << "X specific logic happening" << endl;
    }
    else {
      cout << "Default behavior" << endl;
    }
  }
};

int main() {
  A<X> ax;
  A<Y> ay;
  ax.somefunction(); // prints "X specific logic happening"
  ay.somefunction(); // prints "Default behavior"
}

typeid可与模板一起使用以提取模板参数的类型 - 如下所述:

// expre_typeid_Operator_3.cpp
// compile with: /c
#include <typeinfo>
template < typename T > 
T max( T arg1, T arg2 ) {
   cout << typeid( T ).name() << "s compared." << endl;
   return ( arg1 > arg2 ? arg1 : arg2 );
}

取自:http://msdn.microsoft.com/en-us/library/fyf39xec(v=vs.80).aspx

请注意,name()的值是实现定义的。