从 std::istream 读取时,是否有比 reinterpret_cast<char*> 更好的选择?

Is there a better option than reinterpret_cast<char*> when reading from std::istream?

我有如下一段代码:

std::istream is;
// ... stream initialization ... 
while(is)
{
  uint32_t next4Bytes = 0;
  is.read(reinterpret_cast<char*>(&next4Bytes), 4);
  if(next4Bytes == 218893066)
  {
    is.seekg(-4, std::ios_base::cur);
    break;
  }
  else
    is.seekg(-3, std::ios_base::cur);
}

是否有比 reinterpret_cast<char*> 更好的方法将 4 个字节从 std::istream 读入 uint32_t? (显然不是 c 风格的转换)

我认为没有,我认为您也不需要。您正在使用四个字节和 re-interpreting 它们; reinterpret_cast 准确描述了您的意图。

可以用C-style cast,其实一样但是写起来更短

is.read((char*)&next4Bytes, 4);

尽管如此,您可能希望将该转换包装在模板化 reader 函数中:

template<typename T>
std::streamsize read(T* out, std::istream& stream, size_t count=1) {
    stream.read(reinterpret_cast<char*>(out), sizeof(T)*count);
    return stream.gcount();
}

如果您不关心读取数组,您甚至可以省略 count 参数并使其更简单。有一些方法可以根据您自己的需要对其进行修改。如果您对实际读取了多少值而不是读取了多少字节感兴趣,则可以将它除以 sizeof(T) 而不是 return 只计算 gcount。 (这与 fread 的 return 值的工作方式非常相似)。或者,如果无法读取所有数据,您可以抛出异常。

这个想法是 read 读取字节,而不是 >> 运算符,后者是高级构造。

您将字节读取到 charunsigned char,因为这就是字节的全部内容。试图解决这个问题几乎取消了 read 读取字节的目的。

因此,如果困扰您的是 reinterpret_cast 的冗长,请使用模板。

如果困扰您的是必须将字节读入整数这一事实,请尝试首先将整数存储为字符串,然后使用适当的 >> 运算符将其提取。