C++风格的将无符号字符指针转换为常量字符指针的强制转换

84

我有:

unsigned char *foo();
std::string str;
str.append(static_cast<const char*>(foo()));

错误:invalid static_cast from type ‘unsigned char*’ to type ‘const char*’

在 C++ 中,这里进行强制类型转换的正确方式是什么?


3
通常使用unsigned char来保存Unicode风格的字符串,你确定要直接转换它而不是先将内容转换过来吗? - Greg Domjan
7个回答

65

char *const unsigned char *是被认为无关的类型。因此您需要使用reinterpret_cast

但是,如果您从const unsigned char*转换为非const类型,则需要先使用const_castreinterpret_cast不能去除constvolatile限定符。


4
“Unrelated”在这里是误导性的:它给人一种印象,似乎你不能从一个类型转换为另一个类型。我正在阅读2014年的一个草案,“3.9.1基本类型”,它说:“char、signed char和unsigned char占用相同的存储空间,并具有相同的对齐要求”。这就是一种关系。或者这里有一个更易读的链接:https://en.cppreference.com/w/cpp/language/types#Character_types - Victor Sergienko

57

尝试使用 reinterpret_cast

unsigned char *foo();
std::string str;
str.append(reinterpret_cast<const char*>(foo()));

52

reinterpret_cast


8
@jesses.co.tt,谢谢你的反对票。这篇文章被赞同的关键特点是它的时效性。其他答案提供了各种详细信息,最好单独阅读和赞同。如果@JaredPars的回答涵盖了您所需要的内容,我建议使用那个答案并/或者给它点赞。您可能已经注意到我花了时间改善那些答案的格式。我真的不认为将这个答案扩展到包含其他答案的内容有任何意义。 - Ruben Bartelink
3
好的,我理解你在这里的理由,并且整个页面来看,我同意没有必要重新表达......我猜很难花时间查看整个页面和时间戳,而不是仅根据每个答案的价值进行判断......但我接受了这一点(尤其是来自一个比我拥有55倍声望的人!) - jesses.co.tt
1
@jesses.co.tt 别担心,我理解你的观点,你并没有太错。老实说,我已经很久没有像这样在高流量标签中“竞争”了,用最快的枪手式回答。但是,即使这是正确的做法(在另一天,我也会很愉快地辩论),你也不会通过删除你的答案来获得这种声望水平。好了,我们有一堵文字墙挡住了视线,所以你的任务完成了 :P - Ruben Bartelink
26
我特别喜欢你如此关注于喊“第一!”而没有费心进行基本格式化。 - OJFord
8
这个回答真的没有任何用处,它没有提供任何信息。 - OYRM
@RubenBartelink,如果你的回答没有任何意义,也不能独立存在,那么为什么还要回答呢?如果你不明白为什么这个答案需要扩展,也许你应该将其删除。 - Bulbasaur

20

unsigned char* 基本上是一个字节数组,应该用来表示原始数据而不是字符串。Unicode字符串通常被表示为wchar_t*。

根据C++标准,unsigned char* 和char*之间的reinterpret_cast是安全的,因为它们具有相同的大小、构造和约束。一般情况下,我尽量避免使用reinterpret_cast,甚至比const_cast更少使用。

如果static_cast在您所做的事情中失败了,您可能需要重新考虑您的设计,因为如果您正在使用C++,您可能希望利用“加加”部分提供的内容,并使用string类和STL(也就是std::basic_string可能更适合您)。


6

由于需要回复的答案太多,因此我会在这里留下另一个答案。

在您的情况下,您可以并且应该使用reinterpret_cast<>

str.append(reinterpret_cast<const char*>(foo()));

因为尽管这两个是不同的类型,但是2014标准第3.9.1章节基本类型[basic.fundamental]表明它们之间存在着关联:
“char”,“signed char”和“unsigned char”是三种独立的类型,统称为窄字符类型。一个“char”,一个“signed char”和一个“unsigned char”占用相同数量的存储空间并具有相同的对齐要求(3.11),也就是说它们具有相同的对象表示形式。
(选段由我)
以下是一个可用的链接:https://en.cppreference.com/w/cpp/language/types#Character_types 使用来处理Unicode/多字节字符串已过时:Should I use wchar_t when using UTF-8?

6

您需要使用reinterpret_cast<>,因为您要转换的两种类型彼此不相关。


-4
希望它有所帮助。 :)
const unsigned attribName = getname();
const unsigned attribVal = getvalue();
const char *attrName=NULL, *attrVal=NULL;
attrName = (const char*) attribName;
attrVal = (const char*) attribVal;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接