0

I have the following code that throws errors during compilation whenever I template the parent of the structs I am using within a union. The minimalized code looks as such:

#include <array>
#include <cstdint>
#include <iostream>

template<bool side>
struct Base {
    union Members;
    static Members members;
};

template<bool side>
struct Sub1 : Base<side> {
    struct Members {
        std::array<uint8_t, 8> intArray;
    };
};

template<bool side>
struct Sub2 : Base<side> {
    struct Members {
        std::array<uint16_t, 4> intArray;
        uint32_t length;
    };
};

template<bool side>
union Base<side>::Members {
    Sub1<side>::Members mem1;
    Sub2<side>::Members mem2;
};

void main() {

    std::cout << sizeof(Base<true>::Members);
}

The errors being thrown are C2061 syntax error: identifier 'Members' and C2238 unexpected token(s) preceding ';'

If it helps I am compiling using Visual studio 2019 and using C++17.

I have tried removing the inheritance from the subclasses which does work, and removing the template from the parent class which works as well, but I cannot find the reason why the above code fails to compile. This code is minimalized so although it does not appear that the inheritance is accomplishing anything in the shown code, in the actual code it is used so I would like to keep it if at all possible.

For reference I will include code below that includes all three attempts which can be toggled using the macro labelled "templateSwitch" creating compilation branches as follows:

0 - compiling with no templates

1 - being the erroneous code

2 - compiling with templated sublasses with inheritance to a non templated parent

3 - compiling with templated class named Base but no inheritance (the classes labelled Sub1 and Sub2 are not children of the Base class).

#define templateSwitch 1

#if templateSwitch == 3
//COMPILES - Only the Base is a template, removed inheritance
template<bool side>
struct Base {
    union Members;
    static Members members;
};

struct Sub1 {
    struct Members {
        std::array<uint8_t, 8> intArray;
    };
};

struct Sub2 {
    struct Members {
        std::array<uint16_t, 4> intArray;
        uint32_t length;
    };
};

template<bool side>
union Base<side>::Members {
    Sub1::Members mem1;
    Sub2::Members mem2;
};

void main() {

    std::cout << sizeof(Base<true>::Members);
}

#elif templateSwitch == 2
//COMPILES - Only the subclasses are templates
struct Base {
    union Members;
    static Members members;
};

template<bool side>
struct Sub1 : Base {
    struct Members {
        std::array<uint8_t, 8> intArray;
    };
};

template<bool side>
struct Sub2 : Base {
    struct Members {
        std::array<uint16_t, 4> intArray;
        uint32_t length;
    };
};

union Base::Members {
    Sub1<true>::Members mem1;
    Sub2<false>::Members mem2;
};

void main() {

    std::cout << sizeof(Base::Members);
}

#elif templateSwitch == 1
//ERROR - Both the base class and the subclasses are templates
template<bool side>
struct Base {
    union Members;
    static Members members;
};

template<bool side>
struct Sub1 : Base<side> {
    struct Members {
        std::array<uint8_t, 8> intArray;
    };
};

template<bool side>
struct Sub2 : Base<side> {
    struct Members {
        std::array<uint16_t, 4> intArray;
        uint32_t length;
    };
};

template<bool side>
union Base<side>::Members {
    Sub1<side>::Members mem1;
    Sub2<side>::Members mem2;
};

void main() {

    std::cout << sizeof(Base<true>::Members);
}

#else
//COMPILES - Neither the base class nor the subclasses are templates
struct Base {
    union Members;
    static Members members;
};

struct Sub1 : Base {
    struct Members {
        std::array<uint8_t, 8> intArray;
    };
};

struct Sub2 : Base {
    struct Members {
        std::array<uint16_t, 4> intArray;
        uint32_t length;
    };
};

union Base::Members {
    Sub1::Members mem1;
    Sub2::Members mem2;
};

void main() {

    std::cout << sizeof(Base::Members);
}
#endif
timrau
  • 22,578
  • 4
  • 51
  • 64
Ryoku
  • 397
  • 2
  • 16

0 Answers0