使用带模板的dynamic_cast

uml*_*ute 5 c++ inheritance templates dynamic-cast

在C++中实现基于模板的工厂时,我创建了以下allocator函数来实例化给定的子类:

template<class ChildClass, class ParentClass>
ParentClass* allocator() {
   ChildClass *child  = new ChildClass();
   ParentClass*parent = dynamic_cast<ParentClass*>(child);
   if(NULL==parent) {
     delete child;
     return NULL;
   }
   return parent;
}
Run Code Online (Sandbox Code Playgroud)

一切正常,但是当通过静态代码分析工具(如coverity)运行代码时,该delete child;行被标记为逻辑死代码.

我执行运行时检查的原因是断言,即ChildClass派生自ParentClass.

现在我明白了,在模板扩展期间,编译器已经知道是否ChildClass从中派生ParentClass,并且dynamic_cast只在运行时进行评估.

所以运行时检查在逻辑上是死代码,如果ChildClass它确实来自ParentClass(在这种情况下,如果已成功分配,dynamic_cast将始终返回).non-NULLChildClass

有没有办法确保ChildClassParentClass编译时(模板扩展时间)派生出来?

afaik,模板和继承在C++中是无关的,但我可能会遗漏一些明显的东西.

限制

遗憾的是,代码应该在较旧的编译器上编译(例如,C++ - Visual Studio 6附带的实现),它排除了任何较新的扩展,如C++11-features

jua*_*nza 7

你可以使用std::is_base_of:

constexpr bool is_base = std::is_base_of<ParentClass, ChildClass>::value;
Run Code Online (Sandbox Code Playgroud)

你可以在a中使用它static_assert来表示编译器错误,ChildClass而不是派生的ParentClass.

static_assert(std::is_base_of<ParentClass, ChildClass>::value,
              "ParentClass is not base of ChildClass");
Run Code Online (Sandbox Code Playgroud)

如果您没有C++ 11支持,则可以使用boost::is_base_ofBOOST_STATIC_ASSERT.