объединение constexpr с членами POD Struct с использованием расширений пакета параметров - PullRequest
0 голосов
/ 07 марта 2019

Я пытаюсь создать constexpr union , который включает 3 типа. Объединение может содержать необработанные массивы uint8_t array или фиксированной длины PODTypeA или PODTypeB. Длины этих массивов известны во время компиляции и задаются значениями constexpr.

Структуры POD очень просты:

struct PODTypeA {
    int a;
    int b;
};

или

struct PODTypeB {
    uint32_t a;
    uint32_t b;
};

Встроенная среда не имеет стандартной библиотеки шаблонов. Поэтому я не могу использовать constexpr std::array<T,N>, который намного упростит задачу.

Ниже показана реализация массива constexpr Array(const Args&... args), которая должна функционировать как элемент данных constexpr для хранения полей массива.

template <typename T, std::size_t Size>
struct Array {
    T data[Size];
    template <typename ...Args>
    constexpr Array(const Args&... args)
        : data{ args... }
    {}
};

Я не до конца понимаю, как работает расширение пакета параметров (эффективно memcpy (извлекает) массив через компилятор для указанного члена объединения). Если бы кто-то мог объяснить, что это было бы плюсом. Я нашел описанный выше модуль расширения пакета параметров массива в проверенном ответе на следующее переполнение стека вопрос (где также есть живой пример).

Я поместил это в coliru проект, но у меня много проблем с компиляцией.

У меня есть 3 конструктора для объединения, каждый из которых принимает параметр массива фиксированной длины следующим образом:

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;
};

А вот как я ожидаю использовать его:

int main()
{
    PODTypeA[UnionStruct::gArraySizeA] arrayTypeA = {{1,2}, {3,4}};
    // construct union from fixed PODTypeA array with 2 elements
    UnionStruct foo (arrayTypeA);
}

Компилятор выдает следующие ошибки:

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}};
             ^
...