显然,编译器认为它们是不相关的类型,因此reinterpret_cast
需要。 为什么会出现这样的规则?
Answer 1:
它们是完全不同的类型看标准:
3.9.1基本类型[basic.fundamental]
)声明为字符CHAR 1个对象应足够大来存储执行的基本字符集中的任何成员。 如果从这个组的字符被存储在字符对象时,该角色对象的积分值等于该字符的单个字符的文本形式的值。 它是实现定义一个char对象是否能够维持负值。 字符可以被显式声明未签名或
签。 平原字符,符号的字符,和unsigned char三种不同类型。 炭,一个符号的字符,以及一个无符号字符占用存储相同量的并具有相同的对准要求(basic.types); 也就是说,它们具有相同的对象表示。 对于字符类型,对象的所有位
代表参加的值表示。 无符号字符类型,则该值表示的所有可能的位模式代表号码。 这些要求不持有其他类型。 在任何特定实现中,一个普通的char对象可以采取无论是作为一个符号的字符或无符号的字符相同的值; 其中之一是实现定义。
因此,类似于这也是为什么以下失败:
unsigned int* a = new unsigned int(10);
int* b = static_cast<int*>(a); // error different types
a
和b
是完全不同的类型,真的是你在质疑就是为什么的static_cast等限制性的时候才可以执行没有问题如下
unsigned int a = new unsigned int(10);
int b = static_cast<int>(a); // OK but may result in loss of precision
和为何不能推断出该目标类型是相同的位域的宽度和可被表示? 它可以为标量类型但指针做到这一点,除非目标从源,并且要执行一个垂头丧气然后指针之间的铸造是行不通的。
Bjarne的Stroustrop指出为什么static_cast
的是在这个环节有用: http://www.stroustrup.com/bs_faq2.html#static-cast但缩写形式是为用户清楚说明什么他们的意图,并给予编译器有机会来检查你正打算可以实现的,因为static_cast
不支持不同的指针类型之间铸造那么编译器可以捕捉这个错误,以提醒用户,如果他们真的想这样做转换,他们则应该使用reinterpret_cast
。
Answer 2:
你想不相关的指针转换用的static_cast。 这不是的static_cast是什么。 在这里你可以看到: 类型转换 。
随着的static_cast可以转换数字数据(例如字符为unsigned char应该工作)或指针相关的类(某些遗传有关)。 这既是并非如此。 你想一个不相关的指针转换为另一种,所以你必须使用reinterpret_cast的。
基本上你正在试图做的是编译器一样试图一个char *转换为void *。
好吧,这里的一些额外的想法,为什么允许这是根本错误的。 的static_cast可用于数值类型转换成彼此。 因此,它是完全合法的编写如下:
char x = 5;
unsigned char y = static_cast<unsigned char>(x);
什么也是可能的:
double d = 1.2;
int i = static_cast<int>(d);
如果你在汇编看看这段代码,你会看到第二个投不中d位模式的一个单纯的重新演绎,而是用于转换一些汇编指令都在这里插入。
现在,如果我们扩展这种行为阵列,其中简单地解释位模式的不同方式是足够的情况下,它可能工作。 但是关于铸造双打的阵列整数数组是什么? 这就是你要么必须声明你想简单的位模式的重新诠释 - 有一个机制来调用reinterpret_cast的,或者你必须做一些额外的工作。 正如你所看到的简单的延长指针的static_cast,因为它需要行为类似于static_casting类型的单值/阵列是不够的。 这有时需要额外的代码,它不是明确定义应如何对阵列进行。 在你的情况 - 停在\ 0 - 因为这是惯例? 这是不够的非字符串的情况下(数字)。 会发生什么,如果数据类型的大小改变(如int与上双x86-32bit)?
你想要的行为不能为所有使用情况,这就是为什么它不是在C ++标准进行适当定义。 否则,你将不得不记住的东西,如:“只要他们是整型的,我可以施放此类型的其他具有相同的宽度和......”。 这种方式是完全清楚 - 他们要么是相关的类 - 那么你可以施放指针,或者它们是数值类型 - 那么你可以投的值。
Answer 3:
除了是三分球, unsigned char *
和char *
毫无共同之处(EdChum已经提到一个事实,即char
, signed char
和unsigned char
是三种不同类型)。 你可能会说同样的事情Foo *
和Bar *
指针类型的任何不同的结构。
static_cast
意味着源类型的指针可以被用作目标类型,这需要一个亚型关系的指针。 因此,它不能在你的问题的情况下使用; 你需要的是无论是reinterpret_cast
不正是你想要的东西或C样式转换。