Search code examples
c++c++14

class template instantiation: base class undefined


Given the following class template

template <typename T, typename VT, typename PF, typename ... Sub>
class InheritableAccess;

template <typename T, typename VT, typename PF, typename F, typename ... Sub>
class InheritableAccess<T, VT, PF, F, Sub...> : public InheritableAccess<T, typename F::Type, F, Sub...>{};

template <typename T, typename PF, typename ... Sub>
class InheritableAccess<T, T, PF, Sub...>{};

Trying to instantiate it

internal::InheritableAccess<inheritable, sub1::Type, sub1, sub2> t;

Produces the following compilation error:

Test.h(32,1): error C2504: 'internal::InheritableAccess<T,SubItem2,F>': base class undefined
1>        with
1>        [
1>            T=inheritable,
1>            F=sub2
1>        ]
1>test-project2.cpp(21): message : see reference to class template instantiation 'internal::InheritableAccess<inheritable,SubItem1,sub1,sub2>' being compiled

Why is that?

Runnable code example below:
Test.h

#pragma once

template <typename T, typename A, int8_t I = 0>
struct SubClass
{
    typedef T Type;
    typedef A AttributeType;
    static const int8_t id = I;
};
namespace internal {
    template <typename T, typename VT, typename PF, typename ... Sub>
    class InheritableAccess;

    template <typename T, typename VT, typename PF, typename F, typename ... Sub>
    class InheritableAccess<T, VT, PF, F, Sub...> : public InheritableAccess<T, typename F::Type, F, Sub...>
    {

    };

    template <typename T, typename PF, typename ... Sub>
    class InheritableAccess<T, T, PF, Sub...>
    {
    };
}

template <typename Super, typename ... Sub>
class Inheritable;

Test.cpp

#include <iostream>
#include "Test.h"

class Item {
};

class SubItem1 : Item {};
class SubItem2 : Item {};
class SubItem3 : Item {};

class ItemAttr {};

int main()
{
    using sub1 = SubClass<SubItem1, ItemAttr, 1>;
    using sub2 = SubClass<SubItem2, ItemAttr, 2>;
    using sub3 = SubClass<SubItem3, ItemAttr, 3>;
    using inheritable = Inheritable<Item, sub1, sub2, sub3>;
    internal::InheritableAccess<inheritable, sub1::Type, sub1, sub2> t;
    return 0;
}

Solution

  • The primary internal::InheritableAccess template doesn't have a definition.

    Add:

    namespace internal {
        template <typename T, typename VT, typename PF, typename ... Sub>
        class InheritableAccess{};
    //                         ^^