Search code examples
c++templatesinheritancedynamic-cast

using dynamic_cast with templates


while implementing a template-based factory in C++, i have created the following allocator function to instantiate a given child class:

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;
}

everything works fine, but when running the code through static code-analysis tools like coverity, the delete child; line is flagged as logically dead code.

the reason why i do the runtime-check is to assert, that ChildClass is derived from ParentClass.

now i understand, that during template expansion the compiler already knows whether ChildClass is derived from ParentClass, and that the dynamic_cast is only evaluated during run-time.

so the run-time check is logically dead code, if the ChildClass is indeed derived from the ParentClass (in which case the dynamic_cast will always return non-NULL if ChildClass has been successfully allocated).

but is there a way to ensure that ChildClass is derived from ParentClass during compile-time (template expansion time)?

afaik, templates and inheritance are unrelated in C++, but i might be missing something obvious.

restrictions

unfortunately the code should compile on older compilers (e.g. the C++-implementation that comes with Visual Studio 6) which rules out any newer extension like C++11-features


Solution

  • You can use std::is_base_of:

    constexpr bool is_base = std::is_base_of<ParentClass, ChildClass>::value;
    

    You can use this inside a static_assert to signal a compiler error when ChildClass is not derived from ParentClass.

    static_assert(std::is_base_of<ParentClass, ChildClass>::value,
                  "ParentClass is not base of ChildClass");
    

    If you don't have C++11 support, you can use boost::is_base_of and BOOST_STATIC_ASSERT.