是否可以在初始化列表中避免 static_cast ?
Is it possible to avoid static_cast in initializer list?
在我的代码库中,我经常使用以下语法初始化数组或向量 if bytes:
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
}};
我从 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,
^~~~~~~~~~~~~
编译器建议我添加一个 static_cast 来消除错误。我知道强制转换会起作用,但我想知道是否可以避免强制转换并保持现有语法的优雅?
感谢您的帮助。
没有优雅的解决方法。
事实上,您必须使用强制转换。 foo >> 8
&c。是 int
类型的表达式,您不能依赖初始化列表中的缩小转换。只有不合格的编译器才会避免使用您提供的代码发出诊断。
您可以这样做,而不是多次添加 static_cast:
template <class ... Ts>
std::array<uint8_t, sizeof...(Ts)> make_char_array(Ts && ... ts) {
return {{static_cast<uint8_t>(ts)...}};
}
然后auto bytes = make_char_array(...)
使用与之前相同的参数。
您可能会创建函数:
constepxr uint8_t low_byte(uint16_t n) { return n & 0x00FF; }
constepxr uint8_t high_byte(uint16_t n) { return (n >> 8) & 0x00FF; }
然后
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)
}};
在我的代码库中,我经常使用以下语法初始化数组或向量 if bytes:
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
}};
我从 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,
^~~~~~~~~~~~~
编译器建议我添加一个 static_cast 来消除错误。我知道强制转换会起作用,但我想知道是否可以避免强制转换并保持现有语法的优雅?
感谢您的帮助。
没有优雅的解决方法。
事实上,您必须使用强制转换。 foo >> 8
&c。是 int
类型的表达式,您不能依赖初始化列表中的缩小转换。只有不合格的编译器才会避免使用您提供的代码发出诊断。
您可以这样做,而不是多次添加 static_cast:
template <class ... Ts>
std::array<uint8_t, sizeof...(Ts)> make_char_array(Ts && ... ts) {
return {{static_cast<uint8_t>(ts)...}};
}
然后auto bytes = make_char_array(...)
使用与之前相同的参数。
您可能会创建函数:
constepxr uint8_t low_byte(uint16_t n) { return n & 0x00FF; }
constepxr uint8_t high_byte(uint16_t n) { return (n >> 8) & 0x00FF; }
然后
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)
}};