Convert structure to constexpr uint8_t array

I need to create a constexpr array from bytes from a constexpr struct.

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

I tried to extract it from union:

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

but it is not suitable for gcc and msvc compilers to access d instead of the initialized member o. It works when initializing a non constexpr object, as shown below.

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

But that is not what I need. Is there any way to do this?

+5
source share
1 answer

What you want is impossible. In your code, you are trying to access the initialized member in the constexpr context, which is good. The error is that you are then trying to access an inactive member that is not allowed for [expr.const # 2.8] :

The expression e is an expression of a constant constant if the estimate e, following the rules of an abstract machine, evaluates one of the following expressions:

...

  • an lvalue-to-rvalue transformation that applies to a glvalue that refers to an inactive member of a union or its subobject;

Now an alternative is to attempt to serialize the object bytes in the old way, via reinterpret_cast , reinterpret_cast<const uint8_t*>(&a) . Again reinterpret_cast allowed allowed in the constexpr context at 2.15 (same section). I suspect that the reason you cannot do this is because it is not portable.

+2
source

Source: https://habr.com/ru/post/1274524/


All Articles