0

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;
}
Niclas Lindgren
  • 542
  • 6
  • 23
  • [to inherit from a class you need the definition](https://stackoverflow.com/a/74560490/12002570) – Jason Mar 08 '23 at 13:28

2 Answers2

1

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

Add:

namespace internal {
    template <typename T, typename VT, typename PF, typename ... Sub>
    class InheritableAccess{};
//                         ^^
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
1

you have to fully finish the BODY of a class definition before you can use derived things (such as deriving classes from it).

Your base class of all

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

does not yet have a body,

Synopsis
  • 190
  • 10