在C++ 11中声明char十六进制常量

Dam*_*ien 7 c++ hex char c++11

在我们代码的各种低级部分中,我们需要将特定字节发送到设备以使事情发生.因此,我们有很多代码如下:

const char magic_bytes[] = { 0x01, 0xFA, 0x92 };
Run Code Online (Sandbox Code Playgroud)

这导致错误(在GCC 4.7.2上)

test_char.cpp:6:51: warning: narrowing conversion of ‘250’ from ‘int’ to ‘const char’ inside { } is ill-formed in C++11 [-Wnarrowing]
Run Code Online (Sandbox Code Playgroud)

因为0xFA超出-128到127的范围.

我能想到两种解决方法:

const char magic_bytes[] = { static_cast<char>(0x01), static_cast<char>(0xFA), static_cast<char>(0x92) };
Run Code Online (Sandbox Code Playgroud)

要么:

const unsigned char magic_bytes[] = { 0x01, 0xFA, 0x92 };
Run Code Online (Sandbox Code Playgroud)

两者都是丑陋的(第一种情况),或者有其他缺点(在后者的情况下必须转换为(const char*))

有没有更好的方法来声明这些字符串?

ipc*_*ipc 4

C++11 为您提供了可变参数模板GCC支持已经存在了一段时间)来解决这个问题。

template <typename... A>                                                                 
constexpr std::array<char, sizeof...(A)> byte_array(A... v)                              
{ return std::array<char, sizeof...(A)>{{static_cast<char>(v)...}}; }                    

constexpr auto arr = byte_array( 0x01, 0xFA, 0x92 );
Run Code Online (Sandbox Code Playgroud)

或者避免重复调用.data()将其传递给 C 函数:

template <std::size_t S>
struct byte_array {
  char data_[S];
  char *data() { return data_; }
  operator char*() { return data_; }

  const char *data() const { return data_; }
  operator const char*() const { return data_; }

  constexpr std::size_t size() const { return S; }

  // one could add support for begin/end and things like that
};

template <typename... A>
constexpr byte_array<sizeof...(A)> make_byte_array(A... v)
{ return byte_array<sizeof...(A)>{{static_cast<char>(v)...}}; }

// beside constexpr, this can be also non-const
auto magic_bytes = make_byte_array( 0x01, 0xFA, 0x92 );
strtok(magic_bytes, "why?");
Run Code Online (Sandbox Code Playgroud)

与普通字符数组相比,没有任何开销。