6

在我的代码库中,我经常使用以下语法初始化数组或向量 if 字节:

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 来消除错误。我知道演员表会起作用,但我想知道是否有可能避免演员表并保持语法像现在一样优雅?

谢谢您的帮助。

4

3 回答 3

4

您可以执行以下操作,而不是多次添加 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(...)使用与以前相同的论点。

于 2017-10-03T13:49:29.297 回答
3

没有优雅的出路。

事实上,你必须使用演员表。foo >> 8&C。是 type 的表达式int,并且您不能依赖于初始化列表中的缩小转换。只有不符合标准的编译器会避免使用您提供的代码发出诊断。

于 2017-10-03T13:37:04.030 回答
2

您可以创建函数:

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)
}};
于 2017-10-03T14:57:10.910 回答