是否可以使用dynamic_cast进行模板类型检查?

时间:2013-01-10 20:12:24

标签: c++

    template <class T> void checkObject(T genericObject)
    {
      MyClassA* a = dynamic_cast<MyClassA*>(genericObject);
      if (a != NULL)
      {
        //we know it is of type MyClassA
      }
      MyClassB* b = dynamic_cast<MyClassB*>(genericObject);
      if (b != NULL)
      {
        //we know it is of type MyClassB
      }
    }

这样的事情可能吗?我们有模板类型,但我们想知道它的实际类型?

3 个答案:

答案 0 :(得分:7)

在模板世界中,您可能只想为每种类型专门化模板,而不是进行运行时检查,即

 template<typename T>
 void foo(T obj);

 template<>
 void foo<MyClassA>(MyClassA obj) {
 }

 template<>
 void foo<MyClassB>(MyClassB obj2) {
 }

这将允许编译器在编译时通过推断你的args来生成正确的模板。

注意这仅根据实例的静态类型解析,即没有编译时知道您的变量是MyClassC,它继承自MyClassB,因此应该使用通用表格。所以这不起作用:

  MyClassC* cinstance = new MyClassC();
  foo(cinstance); //compiler error, no specialization for MyClassC

一般来说,这指向编译时和运行时多态是非常不同的系统的一般规则。模板严格地处理静态类型领域而不知道继承。这可能会让来自Java / C#的人们感到惊讶,这些人在这两个功能之间实现了更加无缝的集成。

对于类的功能的运行时专业化,您的选项是

  1. 定义虚拟方法 - 可能不合适,具体取决于此功能是否真正属于此对象的一部分
  2. 使用dynamic_cast(你目前正在做的事情) - 有些不赞成,但可能是每个人都能获得的最直接的解决方案。
  3. Visitor Pattern - 一种设计模式,使用重载在运行时解析为正确类型的函数。

答案 1 :(得分:4)

可能但MyClassAMyClassB 必须至少有一个虚拟成员函数才能使dynamic_cast正常工作。我也相信你实际上想要在函数的签名中使用(T* genericObject)而不是T genericObject(否则就没有意义)。

基于模板特化的解决方案适用于 静态多态,但我相信问题是如何启用 运行时检测输入的类型。我想这个模板是用一个指针调用的,该指针的类型是MyClassA 的超类或 MyClassB的超类。 模板专业化将失败在这种情况下提供正确的答案。

无论如何,我有一种强烈的感觉,你正试图做错事来达到你想要达到的目标(不管它是什么)。当您发布此类问题时,我建议您明确哪里,您的目标;这个可能只是沿着错误路径的障碍

答案 2 :(得分:1)

是的,这是可能的。请注意,动态转换在运行时发生,模板生成代码在durign编译。因此,该函数仍将生成,但会在运行时针对您描述的情况进行检查。

编辑:看看Doug T.的答案,找到正确的做法。