Search code examples
c++c++11type-traits

Initialize base subobject with dependent type name in derived class


Given this sample code with class C deriving from A or B depending on policy

#include <iostream>
#include <type_traits>

struct A
{
    A(int a) { std::cout << a << "\n"; }
};

struct B
{
    B(int a) { std::cout << -a << "\n"; }
};

template<bool>
struct policy;

template<>
struct policy<true> { typedef A type; };

template<>
struct policy<false> { typedef B type; };

template<typename T>
struct C : public policy<std::is_polymorphic<T>::value>::type
{
    C() : /* ????? */(5) {}
};

int main()
{
    C<int> a; // should print -5
    C<std::ostream> b; // should print 5
}

How do I initialize the base class of C? (or, if it's not possible, is there a workaround?)


Solution

  • Do it just the way you found the base class of C:

    template<typename T>
    struct C : public policy<std::is_polymorphic<T>::value>::type
    {
        C() : policy<std::is_polymorphic<T>::value>::type(5) {}
    };
    

    Of course, to make it more readable, you can also add a typedef (maybe you will need the base class multiple times within C, then it's worth it). This would look like this:

    template<typename T>
    struct C : public policy<std::is_polymorphic<T>::value>::type
    {
        typedef typename policy<std::is_polymorphic<T>::value>::type Base;
        C() : Base(5) {}
    };
    

    To make it a little less ugly, you could also add another layer of indirection, e.g. a template class BaseForC that yields the correct base as BaseForC<T>::type and encapsulates what policy and is_polymorphic are doing now into one class.