当两个链接的 static_cast 可以完成它的工作时,为什么我们在 C++ 中有 reinterpret_cast ?
假设我想将 A*
转换为 char*
反之亦然,我们有两个选择(我的意思是,我们中的许多人认为我们有两个选择,因为两者似乎都有效!因此混乱!):
Say I want to cast A*
to char*
and vice-versa, we have two choices (I mean, many of us think we've two choices, because both seems to work! Hence the confusion!):
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
即使这样也能正常工作!
Even this works fine!
那么当两个链式 static_cast
可以完成它的工作时,为什么我们在 C++ 中有 reinterpret_cast
?
So why do we have reinterpret_cast
in C++ when two chained static_cast
can do its job?
你们中的一些人可能认为这个主题是之前的主题的重复,例如在这篇文章的底部列出,但事实并非如此.这些主题只是理论上讨论,但他们都没有给出一个例子来说明为什么确实需要reintepret_cast
,以及两个 static_cast
会肯定失败.我同意,一个 static_cast 会失败.但是两个呢?
Some of you might think this topic is a duplicate of the previous topics such as listed at the bottom of this post, but it's not. Those topics discuss only theoretically, but none of them gives even a single example demonstrating why reintepret_cast
is really needed, and two static_cast
would surely fail. I agree, one static_cast would fail. But how about two?
如果两个链式static_cast
的语法看起来很麻烦,那么我们可以编写一个函数模板,让它对程序员更友好:
If the syntax of two chained static_cast
looks cumbersome, then we can write a function template to make it more programmer-friendly:
template<class To, class From>
To any_cast(From v)
{
return static_cast<To>(static_cast<void*>(v));
}
然后我们可以这样使用:
And then we can use this, as:
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
可能有用的这种情况:fstream 读写成员函数的正确转换.
Also, see this situation where any_cast
can be useful: Proper casting for fstream read and write member functions.
所以我的问题基本上是,
So my question basically is,
- 为什么我们在 C++ 中有
reinterpret_cast
? - 请给我举一个例子,其中两个链式
static_cast
肯定无法完成相同的工作?
- Why do we have
reinterpret_cast
in C++? - Please show me even a single example where two chained
static_cast
would surely fail to do the same job?
- 使用哪个演员表;static_cast 还是 reinterpret_cast?
- 演员从 Void* 到 TYPE*?? : static_cast 或 reinterpret_cast
推荐答案
有些事情 reinterpret_cast
可以做到而 static_cast
的序列无法做到(全部来自 C++03 5.2.10):
There are things that reinterpret_cast
can do that no sequence of static_cast
s can do (all from C++03 5.2.10):
指针可以显式转换为任何足够大的整数类型以容纳它.
A pointer can be explicitly converted to any integral type large enough to hold it.
整数类型或枚举类型的值可以显式转换为指针.
A value of integral type or enumeration type can be explicitly converted to a pointer.
指向函数的指针可以显式转换为指向不同类型函数的指针.
A pointer to a function can be explicitly converted to a pointer to a function of a different type.
类型为 T1
的指向 X
成员的指针"类型的右值可以显式转换为指向 X
成员的指针"类型的右值>Y of type T2
" 如果 T1
和 T2
都是函数类型或都是对象类型.
An rvalue of type "pointer to member of X
of type T1
" can be explicitly converted to an rvalue of type "pointer to member of Y
of type T2
" if T1
and T2
are both function types or both object types.
此外,来自 C++03 9.2/17:
Also, from C++03 9.2/17:
- 一个指向 POD 结构对象的指针,使用
reinterpret_cast
适当转换,指向它的初始成员(或者如果该成员是位域,则指向它所在的单元)反之亦然.
- A pointer to a POD-struct object, suitably converted using a
reinterpret_cast
, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa.
相关文章