c++ - 当两个链接的 static_cast 可以完成它的工作时,为什么我们在 C++ 中有 reinterpret_cast?

标签 c++ casting reinterpret-cast static-cast

假设我想将 A* 转换为 char* 反之亦然,我们有两个选择(我的意思是,我们中的许多人认为我们有两个选择, 因为两者似乎都有效!因此困惑!):

struct A
{
    int age;
    char name[128];
};

A a;
char *buffer = static_cast<char*>(static_cast<void*>(&a)); //choice 1
char *buffer = reinterpret_cast<char*>(&a); //choice 2

两者都可以正常工作。

//convert back
A *pA = static_cast<A*>(static_cast<void*>(buffer)); //choice 1
A *pA = reinterpret_cast<A*>(buffer); //choice 2

即使这样也能正常工作!

那么,当两个链式 static_cast 可以完成它的工作时,为什么我们在C++ 中有reinterpret_cast

你们中的一些人可能会认为此主题与之前的主题(例如本文底部列出的主题)重复,但事实并非如此。这些主题仅在理论上进行讨论,但都没有给出一个示例,说明为什么确实需要 reintepret_cast两个 static_cast 肯定会失败。我同意,一个 static_cast 会失败。但是两个呢?

如果两个链式 static_cast 的语法看起来很繁琐,那么我们可以编写一个函数模板,使其对程序员更友好:

template<class To, class From>
To any_cast(From v)
{
    return static_cast<To>(static_cast<void*>(v));
}

然后我们可以这样使用:

char *buffer = any_cast<char*>(&a); //choice 1
char *buffer = reinterpret_cast<char*>(&a); //choice 2

//convert back
A *pA = any_cast<A*>(buffer); //choice 1
A *pA = reinterpret_cast<A*>(buffer); //choice 2

另外,请查看 any_cast 可能有用的这种情况:Proper casting for fstream read and write member functions .

所以我的问题基本上是,

  • 为什么我们在 C++ 中有 reinterpret_cast
  • 请给我看一个两个链式 static_cast 肯定无法完成相同工作的示例?

最佳答案

reinterpret_cast 可以做一些 static_cast 序列无法做到的事情(全部来自 C++03 5.2.10):

  • 指针可以显式转换为任何大到足以容纳它的整数类型。

  • 整数类型或枚举类型的值可以显式转换为指针。

  • 指向函数的指针可以显式转换为指向不同类型函数的指针。

  • 类型为“T1 类型的 X 成员的指针”类型的右值可以显式转换为“指向 的成员的指针”类型的右值>Y of type T2"如果 T1T2 都是函数类型或都是对象类型。

另外,从 C++03 9.2/17 开始:

  • 一个指向 POD-struct 对象的指针,使用 reinterpret_cast 进行适当转换,指向它的初始成员(或者如果该成员是位域,则指向它所在的单元)反之亦然。

关于c++ - 当两个链接的 static_cast 可以完成它的工作时,为什么我们在 C++ 中有 reinterpret_cast?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5025843/

相关文章:

c++ - 使用 OpenCV 2.4.8 构建 CUDA 5.5

c++ - 铸件内的符号

c++ - 我怎样才能摆脱这个 reinterpret_cast,或者这种用法可以吗?

c++ - Raymond Chen 的单例实现使用狡猾的转换?

c++ - 按名称调用/按值调用

c++ - 错误 C2679 : binary '=' : no operator defined which takes a right-hand operand of type

c++ - "undeclared identifier"实际声明

将 volatile 表达式的结果转换为 void

Java 强制转换(强制转换运算符表达式)

c++ - 如何将 vector<uint8_t> 转换为 unsigned char*