显然编译器认为它们是不相关的类型,因此需要reinterpret_cast。为什么这是规则?
reinterpret_cast
wqlqzqxt1#
它们是完全不同的类型,见标准:3.9.1基本类型1声明为字符(char)的对象应足够大,以存储实现的基本字符集的任何成员。如果字符集中的一个字符存储在字符对象中,则该字符对象的整数值等于该字符的单个字符文字形式的值。由实现定义char对象是否可以保存负值。字符可以显式声明为无符号或signed. * 普通字符、有符号字符和无符号字符是三种不同的类型。* 一个字符、一个有符号字符和一个无符号字符占用相同的存储量,并具有相同的对齐要求(basic.types);也就是说,它们具有相同的对象表示形式。对于字符类型,对象的所有位对于无符号字符类型,值表示的所有可能的位模式都表示数字。这些要求不适用于其他类型。在任何特定的实现中,普通char对象可以接受与有符号char或无符号char相同的值;哪一个是实现定义的。这也是为什么下面的例子失败的原因:
unsigned int* a = new unsigned int(10);int* b = static_cast<int*>(a); // error different types
unsigned int* a = new unsigned int(10);
int* b = static_cast<int*>(a); // error different types
字符串a和b是完全不同的类型,实际上您所质疑的是,当static_cast可以毫无问题地执行以下操作时,为什么它会受到如此严格的限制
a
b
unsigned int a = unsigned int(10);int b = static_cast<int>(a); // OK but may result in loss of precision
unsigned int a = 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。
static_cast
gfttwv5a2#
你试图用static_cast转换不相关的指针。这不是static_cast的作用。这里你可以看到:Type Casting。使用static_cast你可以转换数值数据(例如,char到unsigned char应该可以工作)或指向相关类的指针(通过一些继承相关)。这两者都不是。你想将一个不相关的指针转换为另一个,所以你必须使用reinterpret_cast。基本上,你要做的就是让编译器把一个char * 转换成一个void *。好的,这里有一些额外的想法,为什么允许这样做是根本错误的。static_cast可以用来将数值类型相互转换。所以写下面的代码是完全法律的:
char x = 5;unsigned char y = static_cast<unsigned char>(x);
char x = 5;
unsigned char y = static_cast<unsigned char>(x);
字符串还有可能的是:
double d = 1.2;int i = static_cast<int>(d);
double d = 1.2;
int i = static_cast<int>(d);
型如果你用汇编语言看这段代码,你会发现第二次转换不仅仅是对d的位模式的重新解释,而是在这里插入了一些用于转换的汇编指令。现在,如果我们将这种行为扩展到数组,在这种情况下,简单地用不同的方式解释位模式就足够了,它可能会起作用。但是,将双精度型数组转换为整型数组呢?这就是你要么必须声明你只是想要重新解释位模式-有一个称为reinterpret_cast的机制,或者你必须做一些额外的工作。正如你所看到的,简单地扩展指针/数组的static_cast是不够的,因为它需要表现得类似于static_casting类型的单个值。这有时需要额外的代码,并且不清楚如何定义数组。在你的情况下-在\0处停止-因为这是约定?这对于非字符串的情况(数字)是不够的。如果数据类型的大小发生变化(例如,在x86- 32位上是int还是double),会发生什么?你想要的行为不可能在所有的用例中都被正确定义,这就是为什么它不在C++标准中。否则你必须记住这样的事情:“我可以将这个类型转换为另一个类型,只要它们是整数类型,具有相同的宽度和."。这样就完全清楚了-要么它们是相关的CLASSES -然后你可以转换指针,或者它们是数值类型--那么你可以转换这些值。
7y4bm7vi3#
除了是指针之外,unsigned char *和char *没有任何共同之处(EdChum已经提到了char,signed char和unsigned char是三种不同的类型)。你可以对任何不同的结构说Foo *和Bar *指针类型都是一样的。static_cast意味着源类型的指针可以用作目标类型的指针,这需要一个子类型关系。因此,它不能在您的问题的上下文中使用;您需要的是reinterpret_cast,它完全符合您的要求,或者是C风格的转换。
unsigned char *
char *
char
signed char
unsigned char
Foo *
Bar *
3条答案
按热度按时间wqlqzqxt1#
它们是完全不同的类型,见标准:
3.9.1基本类型
1声明为字符(char)的对象应足够大,以存储实现的基本字符集的任何成员。如果字符集中的一个字符存储在字符对象中,则该字符对象的整数值等于该字符的单个字符文字形式的值。由实现定义char对象是否可以保存负值。字符可以显式声明为无符号或
signed. * 普通字符、有符号字符和无符号字符是三种不同的类型。* 一个字符、一个有符号字符和一个无符号字符占用相同的存储量,并具有相同的对齐要求(basic.types);也就是说,它们具有相同的对象表示形式。对于字符类型,对象的所有位
对于无符号字符类型,值表示的所有可能的位模式都表示数字。这些要求不适用于其他类型。在任何特定的实现中,普通char对象可以接受与有符号char或无符号char相同的值;哪一个是实现定义的。
这也是为什么下面的例子失败的原因:
字符串
a
和b
是完全不同的类型,实际上您所质疑的是,当static_cast可以毫无问题地执行以下操作时,为什么它会受到如此严格的限制型
为什么它不能推断出目标类型是相同的位域宽度并且可以被表示?它可以对标量类型这样做,但对于指针,除非目标是从源派生的,并且您希望执行向下转换,否则指针之间的转换将不起作用。
Bjarne Stroustrop在这个链接中说明了为什么
static_cast
是有用的:http://www.stroustrup.com/bs_faq2.html#static-cast,但在缩写形式中,它是为了让用户清楚地说明他们的意图是什么,并给给予编译器一个机会来检查你想要的是可以实现的,因为static_cast
不支持不同指针类型之间的转换,那么编译器可以捕捉到这个错误来警告用户,如果他们真的想做这个转换,那么他们应该使用reinterpret_cast
。gfttwv5a2#
你试图用static_cast转换不相关的指针。这不是static_cast的作用。这里你可以看到:Type Casting。
使用static_cast你可以转换数值数据(例如,char到unsigned char应该可以工作)或指向相关类的指针(通过一些继承相关)。这两者都不是。你想将一个不相关的指针转换为另一个,所以你必须使用reinterpret_cast。
基本上,你要做的就是让编译器把一个char * 转换成一个void *。
好的,这里有一些额外的想法,为什么允许这样做是根本错误的。static_cast可以用来将数值类型相互转换。所以写下面的代码是完全法律的:
字符串
还有可能的是:
型
如果你用汇编语言看这段代码,你会发现第二次转换不仅仅是对d的位模式的重新解释,而是在这里插入了一些用于转换的汇编指令。
现在,如果我们将这种行为扩展到数组,在这种情况下,简单地用不同的方式解释位模式就足够了,它可能会起作用。但是,将双精度型数组转换为整型数组呢?这就是你要么必须声明你只是想要重新解释位模式-有一个称为reinterpret_cast的机制,或者你必须做一些额外的工作。正如你所看到的,简单地扩展指针/数组的static_cast是不够的,因为它需要表现得类似于static_casting类型的单个值。这有时需要额外的代码,并且不清楚如何定义数组。在你的情况下-在\0处停止-因为这是约定?这对于非字符串的情况(数字)是不够的。如果数据类型的大小发生变化(例如,在x86- 32位上是int还是double),会发生什么?
你想要的行为不可能在所有的用例中都被正确定义,这就是为什么它不在C++标准中。否则你必须记住这样的事情:“我可以将这个类型转换为另一个类型,只要它们是整数类型,具有相同的宽度和."。这样就完全清楚了-要么它们是相关的CLASSES -然后你可以转换指针,或者它们是数值类型--那么你可以转换这些值。
7y4bm7vi3#
除了是指针之外,
unsigned char *
和char *
没有任何共同之处(EdChum已经提到了char
,signed char
和unsigned char
是三种不同的类型)。你可以对任何不同的结构说Foo *
和Bar *
指针类型都是一样的。static_cast
意味着源类型的指针可以用作目标类型的指针,这需要一个子类型关系。因此,它不能在您的问题的上下文中使用;您需要的是reinterpret_cast
,它完全符合您的要求,或者是C风格的转换。