使用参数包扩展与POD Struct成员进行constexpr联合

时间:2019-03-06 23:38:49

标签: c++11 union c++17 constexpr

我正在尝试构造一个包含3种类型的 constexpr联合。联合可以包含原始uint8_t arrayPODTypeAPODTypeB的固定长度数组。这些数组的长度在编译时是已知的,并由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... }
    {}
};

我不完全了解参数包扩展的工作原理(通过编译器将数组有效地存储到指定的并集成员)。如果有人可以解释这将是一个加号。我在下面的堆栈溢出 question 的选中答案中找到了上面的Array模板参数包扩展器(其中还有一个实时示例)。

我将其放在 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}};
             ^

0 个答案:

没有答案