У меня есть 3 подобных объединения c ++, как показано ниже, только U16_u не может быть скомпилировано, а U32_u и U64_u работают хорошо.
Сообщение об ошибке: «reinterpret_cast не является постоянным выражением».
constexpr U16_u( const char* p ) : asU( *reinterpret_cast<const uint16_t*>( p ) ) {};
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Почему то же правило не применяет эти очень похожие типы?
union U16_u {
U16_u() noexcept = default;
constexpr U16_u( const U16_u& ) noexcept = default;
constexpr U16_u( U16_u&& ) noexcept = default;
constexpr U16_u& operator=( const U16_u& ) noexcept = default;
constexpr U16_u& operator=( U16_u&& ) noexcept = default;
constexpr U16_u( uint16_t u ) : asU( u ) {};
constexpr U16_u( int16_t i ) : asI( i ) {};
constexpr U16_u( const char* p )
: asU( *reinterpret_cast<const uint16_t*>( p ) ) {}; //ERROR
constexpr U16_u& operator=( uint16_t u ) noexcept {
asU = u;
return *this;
};
constexpr U16_u& operator=( int16_t i ) noexcept {
asI = i;
return *this;
};
constexpr U16_u& operator=( const char* p ) noexcept {
asU = *reinterpret_cast<const uint16_t*>( p );
return *this;
};
constexpr bool operator< ( U16_u other ) const noexcept {
return asU < other.asU;
};
constexpr bool operator> ( U16_u other ) const noexcept {
return asU > other.asU;
};
constexpr bool operator!=( U16_u other ) const noexcept {
return asU != other.asU;
};
constexpr bool operator==( U16_u other ) const noexcept {
return asU == other.asU;
};
constexpr std::string_view strVw() const noexcept {
return std::string_view( asA, sizeof( uint16_t ) );
};
std::string to_str() const noexcept {
return std::string( asA, sizeof( uint16_t ) );
};
uint16_t asU;
int16_t asI;
char asA[ sizeof( uint16_t ) ];
struct {
uint8_t b0;
uint8_t b1;
};
};
union U32_u {
U32_u() noexcept = default;
constexpr U32_u( const U32_u& ) noexcept = default;
constexpr U32_u( U32_u&& ) noexcept = default;
constexpr U32_u& operator=( const U32_u& ) noexcept = default;
constexpr U32_u& operator=( U32_u&& ) noexcept = default;
constexpr U32_u( uint32_t u ) : asU( u ) {};
constexpr U32_u( int32_t i ) : asI( i ) {};
constexpr U32_u( float f ) : asF( f ) {};
constexpr U32_u( const char* p ) : asU( *reinterpret_cast<const uint32_t*>( p ) ) {};
constexpr U32_u& operator=( uint32_t u ) noexcept {
asU = u;
return *this;
};
constexpr U32_u& operator=( int32_t i ) noexcept {
asI = i;
return *this;
};
constexpr U32_u& operator=( float f ) noexcept {
asF = f;
return *this;
};
constexpr U32_u& operator=( const char* p ) noexcept {
asU = *reinterpret_cast<const uint32_t*>( p );
return *this;
};
constexpr bool operator< ( U32_u other ) const noexcept {
return asU < other.asU;
};
constexpr bool operator> ( U32_u other ) const noexcept {
return asU > other.asU;
};
constexpr bool operator!=( U32_u other ) const noexcept {
return asU != other.asU;
};
constexpr bool operator==( U32_u other ) const noexcept {
return asU == other.asU;
};
constexpr std::string_view strVw() const noexcept {
return std::string_view( asA, sizeof( uint32_t ) );
};
std::string to_str() const noexcept {
return std::string( asA, sizeof( uint32_t ) );
};
uint32_t asU;
int32_t asI;
float asF;
char asA[ sizeof( uint32_t ) ];
struct {
uint16_t w0;
uint16_t w1;
};
struct {
uint8_t b0;
uint8_t b1;
uint8_t b2;
uint8_t b3;
};
};
union U64_u {
U64_u() noexcept = default;
constexpr U64_u( const U64_u& ) noexcept = default;
constexpr U64_u( U64_u&& ) noexcept = default;
constexpr U64_u& operator=( const U64_u& ) noexcept = default;
constexpr U64_u& operator=( U64_u&& ) noexcept = default;
constexpr U64_u( uint64_t u ) : asU( u ) {};
constexpr U64_u( int64_t i ) : asI( i ) {};
constexpr U64_u( double d ) : asD( d ) {};
constexpr U64_u( const char* p ) : asU( *reinterpret_cast<const uint64_t*>( p ) ) {};
//void operator=( const U64_u& o ) volatile noexcept { asU = o.asU; };
constexpr U64_u& operator=( uint64_t u ) noexcept {
asU = u;
return *this;
};
constexpr U64_u& operator=( int64_t i ) noexcept {
asI = i;
return *this;
};
constexpr U64_u& operator=( double d ) noexcept {
asD = d;
return *this;
};
constexpr U64_u& operator=( const char* p ) noexcept {
asU = *reinterpret_cast<const uint64_t*>( p );
return *this;
};
constexpr bool operator< ( U64_u other ) const noexcept {
return asU < other.asU;
};
constexpr bool operator> ( U64_u other ) const noexcept {
return asU > other.asU;
};
constexpr bool operator!=( U64_u other ) const noexcept {
return asU != other.asU;
};
constexpr bool operator==( U64_u other ) const noexcept {
return asU == other.asU;
};
constexpr std::string_view strVw() const noexcept {
return std::string_view( asA, sizeof( uint64_t ) );
};
std::string to_str() const noexcept {
return std::string( asA, sizeof( uint64_t ) );
};
uint64_t asU;
int64_t asI;
double asD;
char asA[ sizeof( uint64_t ) ];
struct {
uint16_t w0;
uint16_t w1;
uint16_t w2;
uint16_t w3;
};
struct {
uint8_t b0;
uint8_t b1;
uint8_t b2;
uint8_t b3;
uint8_t b4;
uint8_t b5;
uint8_t b6;
uint8_t b7;
};
};
Я знаю, что эту проблему можно решить посредством "constexpr U16_u (const char * p): b0 (p [0]), b1 (p [1]) {};" или другие простые методы, но меня интересует вопрос.