我有一个双变量i
,它被转换为名为pointer
的空指针:
double i = 3;
void *pointer = &i;
当我想将空指针转换回我使用的双倍时:
double p = *((double*) pointer);
我想将void指针转换为我将作为char *发送的类型:
char* myType= typeid(i).name();//get the name of type of "i"
int p = *((myType*) pointer); // how to implement?
有可能吗?
答案 0 :(得分:2)
C / C ++不能很好地交换数据类型,例如JavaScript变量 int值的格式将不同于二进制
中的双值格式(浮点)在将其转换为void *后,无法使用typeid获取原始数据类型。另请注意,typeid将在不同的操作系统和编译器上具有不同的输出
double dValue = 77.7;
void* pValue = &dValue;
//output "pV" / pointer void (depending on compiler and OS)
std::cout << typeid(dValue).name() << std::endl;
要使用字符串从void *转换,您可以制定如下规则。或者您可以尝试在特定情况下使用C ++模板函数。
int iOutValue = 0;
double dOutValue = 0;
char* name = "double";
if(!strcmp(name, "int"))
{
iOutValue = *((int*)pValue);
}
else if(!strcmp(name, "double"))
{
dOutValue = *((double*)pValue);
}
答案 1 :(得分:2)
而不是
char* myType= typeid(i).name();//get the name of type of "i"
int p = *((myType*) pointer); // how to implement?
使用
typedef decltype(i) myType;
myType p = *((myType*) pointer);
或更好:
typedef decltype(i) myType;
auto p = *reinterpret_cast<myType*>(pointer);
适用于c ++ 11或更高版本。如果你想在旧的c ++编译器上使用decltype
,可以在boost中进行模拟。
编辑。这可能与您想要做的不同,我想这是这样的:
void myFunction(void* unknownParam) {
typedef (realTypeOf unknownParam) RealType; // <-- this is not real c++
RealType &a = *reinterpret_cast<RealType*>(unknownParam)
//do stuff using 'a'
}
这在C ++中是不可能的,但有一个原因:它没有多大意义。
原因是,myFunction
有效,//do stuff using 'a'
部分应该对最终的RealType
类型有效。因此,它不能依赖RealType
类型具有的任何特征:它不能使用它的任何方法,它不能使用任何运算符,它甚至不能知道它是否是类。基本上,你不能做任何事情,而不是你在void*
已经可以做的事情,所以给这个类型起一个名字并没有多大帮助。
类似于你想要的语言特性(但不完全是它)是类型反射,它在C ++中不存在,但你可以用Java,Objective-C或C#等语言找到它。基本上,你问对象本身是否有某种方法,并最终调用它。 Objective-C
中的一个例子-(void)myFunction:(id)unknownParam {
if([unknownParam respondsToSelector:@selector(myMethod)])
[unknownParam performSelector:@selector(myMethod)]
}
答案 2 :(得分:0)
如果您使用某种变体类型而不是绕过void*
,则可以将其转换回来。
如果使用字符串表示类型,则需要从字符串到实际类型的某种映射。虽然你可以从一个字符串到另一个字符串,但是没有转换回来。
假设您知道您的基础数据在某种程度上始终是数字,那么有一些方法可以使用仅包含数字的特殊离散变量。最简单的方法是存储一个64位int和一个double的并集,一些标志指示你有一个,然后是一个转换为任何数字类型的方法,asDouble()
,asLong()
等