![](/img/trans.png)
[英]Why can't I static_cast a tuple containing a void* to one containing a char*?
[英]Why can I use static_cast With void* but not With char*
我知道reinterpret_cast
主要用于从char*
访问或从char*
。
但是我很惊讶地发现static_cast
可以对void*
进行同样的处理。 例如:
auto foo "hello world"s;
auto temp = static_cast<void*>(&foo);
auto bar = static_cast<string*>(temp);
通过在static_cast
和void*
使用reinterpret_cast
和char*
,我们可以得到什么? 与严格的别名问题有关吗?
一般而言,如果可以将static_cast
任意一种类型隐式转换为另一种类型,则static_cast
可以转换任何两种类型。 包括算术转换,向下转换,向上转换以及与void*
。
也就是说,如果此强制转换有效:
void foo(A a);
B b;
foo(b);
然后static_cast<B>(a)
和static_cast<A>(b)
都将有效。
由于任何指针都可以隐式转换为void*
,因此您的行为很特殊。
reinterpret_cast
通过重新解释值的位模式来进行强制转换。 正如您在问题中所说的那样,通常是在不相关的指针类型之间进行转换。
是的,您可以使用两个static_cast
通过void*
在不相关的指针类型之间进行转换:
B *b;
A *a1 = static_cast<A*>(b); //compiler error
A *a2 = static_cast<A*>(static_cast<void*>(b)); //it works (evil laugh)!
但是,这违反了规则。 如果确实需要,请使用reinterpret_cast
。
您的问题确实包含两个部分:
static_cast
或reinterpret_cast
与指向对象的基础位模式的指针一起工作而不必担心对象类型? reinterpret_cast
是更适合解决此基础位模式的void*
或char*
?
static_cast
:使用隐式和用户定义的转换的组合在类型之间进行转换
实际上,在5.2.9 [expr.static.cast] 13中,该标准给出了示例:
T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
它利用隐式强制转换:
可以将指向任何(可选为cv限定)对象类型
T
的prvalue指针转换为指向(相同为cv限定)void
的prvalue指针。 生成的指针与原始指针值在内存中的位置相同。 如果原始指针是空指针值,则结果是目标类型的空指针值。 *
但是,没有从类型T
的指针到char*
隐式转换。 因此,完成该转换的唯一方法是使用reinterpret_cast
。
reinterpret_cast
:通过重新解释基础位模式在类型之间转换
因此,当您要转换为void*
或char*
您想使用基础位模式来回答问题的第1部分,因此应使用reinterpret_cast
因为它的用途是向读者表示向/从基础位的转换图案。
接下来让我们比较void*
和char*
。 两者之间的决定可能取决于应用程序。 如果要将标准库函数与基础位模式一起使用,请使用该函数接受的类型:
值得注意的是,C ++特定的库更喜欢char*
来指向内存。 出于兼容性原因,保留内存为void*
似乎已保留为此处的指针。 因此,如果在基础位模式上不使用cstring
库函数,请使用C ++特定的库行为来回答问题的第2部分:将char*
首选为void*
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.