假设我想将不同类型的数据推送到标准库堆栈中。为了简单起见,我只采用两种类型:
为此,我需要以下数据结构:
//generic class
class foo {
private:
float x_;
public:
foo(float x) : x_(x){};
};
//simple enum
enum element_type {
footype,
number
};
struct stack_element {
element_type type_;
union {
foo* obj;
int num;
} data;
};
Run Code Online (Sandbox Code Playgroud)
然后我需要在结构体中创建一个构造函数以实现类型双关:
//actually this should be if/else statement in this case but on the code problem I have more types
stack_element(element_type type, foo* obj){
switch(type){
case footype:
this->type_ = type;
this->data.obj = obj;
break;
case number:
this->type_ = type;
// Here comes the type punning
this->data.num = *(int*)&obj;
break;
default: throw("Unknown type");
break;
}
}
Run Code Online (Sandbox Code Playgroud)
然后 main.cc 看起来像这样:
#include <stack>
#include <iostream>
int main(){
foo myobj (3.24);
int a = 2;
std::stack < stack_element > mystack;
mystack.push (stack_element (element_type::footype, &myobj));
mystack.push (stack_element (element_type::number, (foo *) a));
do {
if(mystack.top().type_ == number){
std::cout << (int)mystack.top().data.num << std::endl;
mystack.pop();
}
else{
mystack.top().data.obj->print_foo();
mystack.pop();
}
}while(!mystack.empty());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这将编译一个警告,这显然是有意义的:
main.cpp:73:62:警告:从不同大小的整数转换为指针[-Wint-to-pointer-cast] 73 | mystack.push (stack_element (element_type::number, (foo *) a));
现在基础已经确定,我有几个问题:
不允许变体保存引用、数组或 void 类型。(除非您使用引用包装器。)
我应该使用 std::variant 而不是这个联合/结构吗?
我应该使用 std::variant 而不是这个联合/结构吗?
是的,您应该使用std::variant
而不是struct stack_element
.
我想这不是一个真正安全的代码,对吗?
不,您的代码并不真正安全。