Question

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

Was it helpful?

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.

OTHER TIPS

If "Derived" inherits from "Base", then a pointer a "Derived" can be assigned to a pointer to "Base". I.e.:

void AssignToBase(Derived* derived) {
  Base* base = derived;
} 

... the successful compilation of the above proves that "Derived" inherits from "Base". You can use this in conjunction with SFINAE and static assertions (whether in C++11 or using Boost's static assertion mechanism) to validate that the derived class inherits from the parent class. As juanchopanza notes, C++11 provides a simple std::is_base_of<> type traits class that you can use to test this inheritance relationship.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top