Is it possible to avoid static_cast in initializer list?

两盒软妹~` 提交于 2020-01-13 10:05:10

问题


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.


回答1:


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.




回答2:


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.




回答3:


You might create functions:

constepxr uint8_t low_byte(uint16_t n) { return n & 0x00FF; }
constepxr uint8_t high_byte(uint16_t n) { return (n >> 8) & 0x00FF; }

and then

uint16_t foo = 0x0A0B, bar = 0x0C0D;

// bytes = { 0x0A, 0x0B, 0x0C, 0x0D }
std::array<uint8_t, 4> bytes = {{ high_byte(foo),
                                  low_byte(foo),
                                  high_byte(bar),
                                  low_byte(bar)
}};


来源:https://stackoverflow.com/questions/46545847/is-it-possible-to-avoid-static-cast-in-initializer-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!