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