In my code base I often initialize array or vector if bytes using the following the syntax:
uint16_t foo = 0xAB, bar = 0xCD
// bytes = { 0xA, 0xB, 0xC, 0xD }
std::array<uint8_t, 4> bytes = {{
foo >> 8,
foo & 0x00FF,
bar >> 8,
bar & 0x00FF
}};
I get the following error from clang++:
error: non-constant-expression cannot
be narrowed from type 'int' to 'value_type' (aka 'unsigned char') in initializer list [-Wc++11-narrowing]
foo >> 8,
^~~~~~~~~~~~~
The compiler suggest me to add a static_cast to silence the error. I know the cast will work, but I wonder if it is possible to avoid the cast and to keep the syntax as elegant as it is already ?
Thank you for your help.
Instead of adding static_cast a bunch of times, you could do this:
template <class ... Ts>
std::array<uint8_t, sizeof...(Ts)> make_char_array(Ts && ... ts) {
return {{static_cast<uint8_t>(ts)...}};
}
And do auto bytes = make_char_array(...)
with the same arguments as before.
There's no elegant way out of this.
In fact you must use a cast. foo >> 8
&c. are expressions of type int
, and you must not rely on narrowing conversions in initialiser lists. Only a non-conforming compiler would refrain from issuing a diagnostic with the code you provide.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With