I want to put two (not more) different data types as values into a map as shown in the following example:
typeX A, B, ...;
typeY Z, Y, ...;
void func (typeX) { ... }
void func (typeY) { ... }
std::map <std::string, what_to_put_here??> map;
map["a"] = A;
map["z"] = Z;
...
std::vector<std::string> list;
// This list will be something like "a", "y", ...
for (unsigned int i = 0; i < list.size(); ++i)
func( map[list[i]] )
Obviously this doesn't work, as the map will only accept one data type of value. However, when looping over list
, the call to func()
should be unambiguous since the type of map[list[i]]
is known.
I want to avoid explicit casting or type checking, i.e. something like this:
if (typeid( map[list[i]] ).name() == "typeX")
func( map[list[i]] )
else if (typeid( map[list[i]] ).name() == "typeY")
func( map[list[i]] )
Is this possible? Again, it will be limited to only two different data types.
You want to use boost::variant
:
std::map <std::string, boost::variant<typeX, typeY>>
Are typeX and typeY subclasses of a typeBase class ?
If so, you could do a std::map<std::string,typeBase*>
to store both typeX* and typeY* in the map.
With some metaprogramming you can easily build an heterogenous map which can store any type from a given set of types. Here is an example which does this, without type erasure nor the need to visit the values.
One way to implement a multi-type map is by using the nifty features of std::tuple in C++11, which allows access by a type key. You can wrap this to create access by arbitrary keys. An in-depth explanation of this (and quite an interesting read) is available here:
https://jguegant.github.io/blogs/tech/thread-safe-multi-type-map.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With