有没有一种方法可以声明 std::map 而不需要声明值类型?

3
我需要一个类似于 std::map 容器的东西,它应该长这样: [ "a" => [ "a1" => [ "a11" => 1, "a12" => 0 ], "a2" => 1 ] ] 以下是需要回答的问题:
  1. "a1" 的值是另一个 std::map,而键 "a2" 的值则是整数。在这种情况下,我该如何声明这个 map?
  2. 是否有办法将值更改为其他类型?例如,如果我想将 "a12" 的值更改为 std::vector,应该怎么做?
谢谢!

1
一些简单的建议是,使用Python和Ruby这样的动态语言来做这件事情会更容易。静态类型不适合解决这个问题。有许多可能的解决方案,但它们都涉及将类型嵌入应用程序代码中,可能不适合。 - ceorron
@ceorron 谢谢,是的,在Python和Ruby中做这个要容易得多。实际上,我在尝试将Python代码翻译成C++时遇到了这个问题。 - Zhaojie Tao
6个回答

4

不,你不能直接这样做。考虑使用一些类型擦除设备,最好是类型安全和广为人知的,例如boost::variantboost::any。否则,你可以编写一个包含不透明堆分配缓冲区(传统的void * )的value类,并且你需要根据enum字段的值将其强制转换为某种类型。


1
当使用std::map时,您需要指定值类型。如果您想将不同类型的对象映射到地图上,我认为您有两种可能性:
定义值的基类并声明一个
std::map<int, base_class_t *>

地图,或者更好的选择是
std::map<int, shared_ptr<base_class_t>>

然后您可以插入不同的对象,所有这些对象都是从base_class_t派生出来的。

另一个选项是映射到联合。但我不会那样做;-)


0

我无法完全理解您的问题。我的理解是,您希望插入不同类型的值。第一个键将包含指向该映射中另一个键指向的另一个映射的“int Value”。第二个键将包含一个简单的整数。如果是这种情况,为什么不在映射中使用向量。

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

如果您不确定数据类型,可以使用嵌套映射。对于第二个元素,只需放置一个虚拟键。

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));

这个解决了你的问题吗?


0

我认为,可能一个定义了一个参数的部分模板类可以是你问题的答案。就像这样:

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));
}

因此,您可以使用相同的类来区分预定义的第一个参数和在需要时定义的第二个参数。


0
“a1”键具有另一个std::map的值,但“a2”键具有整数值。在这种情况下,我该如何声明映射?
您无法声明此类映射。映射的所有值都具有相同的类型。
是否有一种方法可以将值更改为另一种类型?例如,如果我想将“a12”的值更改为std::vector?
您可能是指,“是否有一种方法可以将变量的类型更改为另一种类型”。答案是否定的。
但是,可以定义一种类型,该类型可以包含任何类型的数据。实现起来并不简单,但是您很幸运,Boost已经实现了这种类型:boost::any。具有此类值类型的映射可以容纳封装在any对象中的任何类型的值。我建议重新考虑设计,以便您不需要拥有任何类型的对象。

0
不,每个STL容器类型都需要一个确切的类型。对于您的想法,您需要一个可以容纳多种类型的容器类型。为此,您可以使用http://www.boost.org/doc/libs/1_58_0/doc/html/variant.html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接