I am trying construct a constexpr union which wraps 3 types. The union can contain a raw uint8_t array
or fixed length arrays of PODTypeA
or PODTypeB
. The lengths of these arrays are known at compile time and given by constexpr values.
The POD structures are very simple:
struct PODTypeA {
int a;
int b;
};
or
struct PODTypeB {
uint32_t a;
uint32_t b;
};
The embedded environment does not have the standard template library available. As such, I cannot use the constexpr std::array<T,N>
which would make things a lot easier.
Shown below is a constexpr Array(const Args&... args)
array implementation, which should function as a constexpr data member to hold array fields.
template <typename T, std::size_t Size>
struct Array {
T data[Size];
template <typename ...Args>
constexpr Array(const Args&... args)
: data{ args... }
{}
};
I don't fully understand how the parameter pack expansion works (effectively memcpy(ing) the array via the compiler to the specified union member). If someone could explain that it would be a plus. I found the above Array template parameter pack expander in the checked answer to the following stack overlflow question (where there is also a live example).
I put this in a coliru project but I am having lots of compile issues.
I have 3 constructors for the union, each one of these takes a fixed length array parameter as follows:
constexpr static auto gSizeBytes = 2048;
constexpr static int gArraySizeA = 2;
constexpr static int gArraySizeB = 3;
union UnionStruct {
explicit constexpr UnionStruct(
const uint8_t(&rParam)[gSizeBytes] = {})
: byteArray(rParam)
{}
explicit constexpr UnionStruct(
const PODTypeA(&rParam)[gArraySizeA])
: arrayA(rParam)
{}
explicit constexpr UnionStruct(
const PODTypeB(&rParam)[gArraySizeB])
: arrayB(rParam)
{}
Array<uint8_t, gSizeBytes> byteArray;
Array<PODTypeA, gArraySizeA> arrayA;
Array<PODTypeB, gArraySizeB> arrayB;
};
And here is how I expect to use it:
int main()
{
PODTypeA[UnionStruct::gArraySizeA] arrayTypeA = {{1,2}, {3,4}};
// construct union from fixed PODTypeA array with 2 elements
UnionStruct foo (arrayTypeA);
}
The compiler issues the following errors:
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In instantiation of 'constexpr Array<T, Size>::Array(const Args& ...) [with Args = {unsigned char [2048]}; T = unsigned char; long unsigned int Size = 2048]':
main.cpp:34:27: required from here
main.cpp:12:25: error: invalid conversion from 'const unsigned char*' to 'unsigned char' [-fpermissive]
: data{ args... }
^
main.cpp: In instantiation of 'constexpr Array<T, Size>::Array(const Args& ...) [with Args = {PODTypeA [2]}; T = PODTypeA; long unsigned int Size = 2]':
main.cpp:39:24: required from here
main.cpp:12:25: error: invalid conversion from 'const PODTypeA*' to 'int' [-fpermissive]
main.cpp: In instantiation of 'constexpr Array<T, Size>::Array(const Args& ...) [with Args = {PODTypeB [3]}; T = PODTypeB; long unsigned int Size = 3]':
main.cpp:44:24: required from here
main.cpp:12:25: error: invalid conversion from 'const PODTypeB*' to 'uint32_t' {aka 'unsigned int'} [-fpermissive]
main.cpp: In function 'int main()':
main.cpp:54:14: error: expected identifier before numeric constant
PODTypeA[2] arrayTypeA = {{1,2}, {3,4}};
^
main.cpp:54:14: error: expected ']' before numeric constant
PODTypeA[2] arrayTypeA = {{1,2}, {3,4}};
^
]
main.cpp:54:13: error: structured binding declaration cannot have type 'PODTypeA'
PODTypeA[2] arrayTypeA = {{1,2}, {3,4}};
^
main.cpp:54:13: note: type must be cv-qualified 'auto' or reference to cv-qualified 'auto'
main.cpp:54:13: error: empty structured binding declaration
main.cpp:54:17: error: expected initializer before 'arrayTypeA'
PODTypeA[2] arrayTypeA = {{1,2}, {3,4}};
^~~~~~~~~~
main.cpp:56:22: error: 'arrayTypeA' was not declared in this scope
UnionStruct foo (arrayTypeA);
^~~~~~~~~~
main.cpp:56:22: note: suggested alternative: 'gArraySizeA'
UnionStruct foo (arrayTypeA);
^~~~~~~~~~
gArraySizeA
main.cpp:54:13: warning: unused structured binding declaration [-Wunused-variable]
PODTypeA[2] arrayTypeA = {{1,2}, {3,4}};
^