为什么reinterpret_cast不会将'unsigned char'转换为'char'?

4

我正在尝试使用MSVC10编译这个库,但是这个函数让我很头疼:

/*! \brief Read bytes from a \c std::istream
    \param is The stream to be read.
    \param data A pointer to a location to store the bytes.
    \param size The number of bytes to be read.
*/
void _read(std::istream &is, unsigned char *data, int size)
{
    for (int i=0; i < size ; ++i )
      is.get(static_cast<char>(data[i]));
}

错误 C2664:“std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::get(_Elem &)”:无法将参数 1 从“char”转换为“char &”

原始代码使用 static_cast,我尝试使用其他地方建议的 reinterpret_cast,但仍然失败:

错误 C2440:“reinterpret_cast”:无法将类型为“unsigned char”的表达式转换为类型“char”

该库带有unix makefiles。如何解决这个编译错误?


2
使用static_cast将一个值转换为rvalue,你不能将rvalue传递给期望lvalue引用的函数。 - Seth Carnegie
为什么有人想要将 static_cast 转换成不太安全的 reinterpret_cast - David Rodríguez - dribeas
由于在这种情况下 static_cast 无法编译。 - Dženan
4个回答

13

由于定义上来说,reinterpret_cast 不是那样工作的。

如果想要对内存进行重新解释,你必须将 reinterpret_cast 应用于指针或引用。如果你想将 unsigned char 数据重新解释为 char 数据,你实际上必须转换为 char & 类型,而不是 char 类型。

在你的情况下,代码如下:

is.get(reinterpret_cast<char &>(data[i]));

或者你可以走指针的路线,执行

is.get(*reinterpret_cast<char *>(&data[i]));

(这是同一件事情)。


3
因为你需要一个指向char的引用char&,但是类型转换的结果是一个r-value,因此无法绑定到引用上。
你需要像这样的东西:
is.get(reinterpret_cast<char&>(data[i]));

但在这种特殊情况下,您可以/应该使用static_cast<char&>

is.get(static_cast<char&>(data[i]));


static_cast 函数出现错误 C2440: 'static_cast' : 无法将 'unsigned char' 转换为 'char &'。 - Dženan
@Dženan:哦,GCC编译它,但我找不到任何证明它是有效的参考资料,所以我认为它是无效的。删除注释... - rodrigo

1
尝试使用这个替代方案:
void _read(std::istream &is, unsigned char *data, int size)
{
    for (int i=0; i < size ; ++i )
      is.get(reinterpret_cast<char*>(data)[i]);
}

1
除了其他解决强制类型转换问题的答案之外:
为什么不直接使用istream::read一次读取size字节呢?这样可以避免手写for循环,而且速度更快。
void _read(std::istream &is, unsigned char *data, int size) {
    is.read(reinterpret_cast<char*>(data), size);
}

这是我正在尝试编译的一些库。所以我更喜欢尽可能少地进行更改。我也想到使用read会更快。 - Dženan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接