Reputation: 1157
I'm using c++.
I want to create a map
to store any struct in my project.
I.e I have the structers:
struct My_Struct1{ int x;}
struct My_Struct2{float y;}
...
And i want to declare a map:
MyMap[MessageID1] = My_Struct1_obj;
MyMap[MessageID2] = My_Struct2_obj;
....
Which type the MyMap
should be?
map<unsigned int, ? > MyMap;
If i do map<unsigned int, void* >
how i can know if i want to access to int x
or to float y
? I need to do switch case on MessageID?
After i have got the message i want to copy some data from the match block..
Upvotes: 1
Views: 99
Reputation: 1604
You can achieve that via inheritance, create a base struct and inherit both of your structs from that base struct (place some constructor to initialize the data member if you want).
//Your base struct
struct My_Base
{
virtual void foo() {};
};
struct My_Struct1: virtual My_Base
{
public:
int x;
My_Struct1(int _x) { x = _x; }
};
struct My_Struct2 : virtual My_Base
{
public:
float y;
My_Struct2(float _y) { y = _y; }
};
map<unsigned int, My_Base*> _map;
To make it easily understandable, providing the driver or invocation code below.
My_Base* obj1 = new My_Struct1(2);
My_Base* obj2 = new My_Struct2(3.2f);
//Adding some random test data to map
_map[1] = obj1;
_map[2] = obj2;
My_Base* mapObjBase = _map.find(2)->second;
//Downcast the object you retrieved from the map, this downcasting could fail so please note the if here.
if (My_Struct2* mapObj2 = dynamic_cast<My_Struct2*>(mapObjBase))
{
cout << "My_Struct2.y = " << mapObj2->y << endl;
}
else
{
cout << "Error..." << endl;
}
//Some memory cleaning before leaving the code block.
delete obj1;
delete obj2;
Something about dynamic_cast (if you are interested in further reading...)
Upvotes: 3
Reputation: 98446
The easier way would be to create a base class for all your structures and store pointers to that in the map.
struct BaseStruct
{
virtual ~BaseStruct()
{}
};
struct My_Struct1 : BaseStruct { int x; }
struct My_Struct2 : BaseStruct { float y; }
std::map<unsigned int, BaseStruct *> MyMap;
Or you may prefer using a smart pointer to handle the lifetime of the objects.
std::map<unsigned int, std::shared_ptr<BaseStruct> > MyMap2;
std::map<unsigned int, std::unique_ptr<BaseStruct> > MyMap3;
Note the virtual destructor. That is important so that when you delete the objects from the map the memory of the subclasses is properly freed.
PS: Take a look at boost::any
. It may be useful if you don't want or can't use the base struct.
Upvotes: 4
Reputation: 31312
You should declare struct type in following way:
struct My_Struct
{
union
{
int x;
float y;
};
};
Then you can use it in following way:
map<unsigned int, My_Struct> MyMap;
Upvotes: 2