简体   繁体   中英

Is there a way to have a std::map without declare the value type

I need a std::map container have something like:

[ "a" => [ "a1" => [ "a11" => 1, "a12" => 0 ], "a2" => 1 ] ]

  1. The key "a1" have a value of another std::map , but the key "a2" have a value of integer. In this situation, how can I declare the map?

  2. Is there a way to change the value to another type? For example, if I want to change the value of "a12" to a std::vector ?

Thanks.

No, you can't do this straight away. Consider using some type-erasure device, peferably type-safe and well-understood, like boost::variant or boost::any . Otherwise, you can craft a value class that contains an opaque heap-allocated buffer (an old-school void* ) and you are supposed to cast it to a type depending on the value of an enum field.

when using std::map you need to specify value type. If you want to map to objects of different types I think you have two possibilities:

Define a base class for the value and declare a

std::map<int, base_class_t *>

map or, better a

std::map<int, shared_ptr<base_class_t>>

Then you can insert different objects, all derived from base_class_t.

The outher options is map to a union. But I would not do that ;-)

I was not able to understand your question fully.What I got is that you want to insert different types of values. The first key will contain the "int Value" of another map pointed at by another key of that map. the second key will contain a plain integer. If that's the case why not use vector inside a map.

std::map<int, std::vector<int>> mymap;
std::vector <int> vec;
vec.push_back(5);
mymap.insert(make_pair(1, vec));

Further to this if your not sure about datatype. you can also use nested maps. for the second element just put a dummy key.

std::map<int, std::map<int,int>> mymap;
std::map <int, int> mappy;
mappy.insert(make_pair(0,5));
mymap.insert(make_pair(1, mappy));

Does this solve your problem?

The key "a1" have a value of another std::map, but the key "a2" have a value of integer. In this situation, how can I declare the map?

You can't declare such map. All values of a map have the same type.

Is there a way to change the value to another type? For example, if I want to change the value of "a12" to a std::vector?

You probably mean, "Is there a way to chage the type of a variable to another". The answer is no.

However, it is possible to define a type that can enclose data of any type inside. It's not exactly simple to implement, but you're in luck, Boost has implemented such type: boost::any . A map with such value type can then hold a value of any type enclosed in the any -object. I would recommend reconsidering your design so that you don't need to have objects of any type, though.

No, each STL container type needs exact ONE type. For your idea you need a container type which can hold multiple types. For that you can use http://www.boost.org/doc/libs/1_58_0/doc/html/variant.html

I think, likely a partial template class with one parameter defined could be the answer to your problem, Something like this;

template <typename T>
class partialMap : public std::map<int,T>
{
};

int main()
{
  //vector example
  std::vector <int> vec;
  partialMap<std::vector<int>> _vecMap;
  vec.push_back(5);
  _vecMap.insert(make_pair(1, vec));
  //map example
  std::map<int,int> map;
  partialMap<std::map<int,int>> _mapMap;
  vec.push_back(5);
  _mapMap.insert(make_pair(1, map));
}

So, you might use indistinctly the same class with the first parameter predefined and the second one defined in function whatever you need.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM