将struct转换为uint8_t的constexpr数组

omi*_*nns 6 c++ arrays templates constexpr c++17

我需要从constexpr结构中创建constexpr字节数组.

#include <array>

template<typename T>
constexpr std::array<uint8_t, sizeof(T)> o2ba(const T o) {
    return {};
}

struct A {
    int a;
};

int main() {
    constexpr A x{ 1 };
    constexpr auto y = o2ba(x); // y == { 0x01, 0x00, 0x00, 0x00 } for little endian
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我试图从联合中提取它:

template<typename T>
union U {
    T o;
    std::array<uint8_t, sizeof(T)> d;
};

template<typename T>
constexpr std::array<uint8_t, sizeof(T)> o2ba(const T o) {
    return U<T>{o}.d;
}
Run Code Online (Sandbox Code Playgroud)

但它在gcc和msvc编译器上都无法访问d而不是初始化的o成员.它在初始化非constexpr对象时起作用,如下所示.

int main() {
    constexpr A x{ 1 };
    auto y = o2ba(x); // y == { 0x01, 0x00, 0x00, 0x00 } for little endian
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但这不是我需要的.有没有办法做到这一点?

use*_*840 2

你想要的东西是不可能的。在您的代码中,您尝试访问上下文中的已初始化成员constexpr,这很好。错误是您随后尝试访问非活动成员,这是[expr.const#2.8]不允许的:

表达式 e 是核心常量表达式,除非对 e 的求值遵循抽象机的规则,将求值以下表达式之一:

...

  • 左值到右值的转换,应用于引用联合体或其子对象的非活动成员的左值;

现在的替代方法是尝试以旧方式将对象序列化为字节,via reinterpret_cast, ie reinterpret_cast<const uint8_t*>(&a)。同样,在2.15(同一节)的上下文reinterpret_cast中不允许使用。constexpr我怀疑你不能这样做的原因是因为它不可移植。