2008-10-30 51 views
28

我想要一个具有齐次键类型但异构数据类型的映射。你如何制作异构boost :: map?

我希望能够像做(伪代码):

boost::map<std::string, magic_goes_here> m; 
m.add<int>("a", 2); 
m.add<std::string>("b", "black sheep"); 

int i = m.get<int>("a"); 
int j = m.get<int>("b"); // error! 

我能有一个指向基类的数据类型,但宁可不要。

我从来没有使用过提升,但看过融合库,但无法弄清楚我需要做什么。

感谢您的帮助。

+2

`boost :: variant` – 2014-02-10 22:41:55

+0

如果你知道所有可能的类型,你可能想要在地图中填充,然后`boost :: variant`将很好。如果你真的想要任何类型,那么`boost :: any`就是要走的路。 – Kurt 2014-03-07 05:21:58

回答

34
#include <map> 
#include <string> 
#include <iostream> 
#include <boost/any.hpp> 

int main() 
{ 
    try 
    { 
     std::map<std::string, boost::any> m; 
     m["a"] = 2; 
     m["b"] = static_cast<char const *>("black sheep"); 

     int i = boost::any_cast<int>(m["a"]); 
     std::cout << "I(" << i << ")\n"; 

     int j = boost::any_cast<int>(m["b"]); // throws exception 
     std::cout << "J(" << j << ")\n"; 
    } 
    catch(...) 
    { 
     std::cout << "Exception\n"; 
    } 

} 
+1

而不是cumbersome_cast,你可以使用`std :: decay`。 – 2012-03-17 01:17:05

9

How can I build a <favorite container> of objects of different types?

你不能,但你可以伪造它相当不错。在C/C++中,所有数组都是同类的(即元素都是相同的类型)。但是,通过额外的间接层,您可以给出异构容器的外观(异构容器是包含的对象具有不同类型的容器)。

有两种情况的异构容器。

第一种情况发生在您想要存储在容器中的所有对象都从公共基类中公开派生时。

第二种情况发生在对象类型不相交时 - 它们不共享公共基类。
这里的方法是使用句柄类。容器是句柄对象的容器(通过值或指针,您的选择;按价值更容易)。每个句柄对象知道如何“坚持”(即保持一个指向)你想要放入容器的一个对象。您可以使用具有多种不同类型指针的单个句柄类作为实例数据,也可以使用影响您希望包含的各种类型的句柄类层次结构(要求容器具有句柄基类指针)。这种方法的不足之处在于,每次更改可以包含的类型集时,都会打开句柄类来进行维护。好处是您可以使用句柄类来封装大部分内存管理和对象生命周期的丑陋。因此,即使在第一种情况下,使用手柄物体也是有益的。

5

谢谢大卫,那正是我所需要的。这是工作解决方案。

#include <iostream> 
using std::cout; 
using std::endl; 

#include <map> 
#include <boost/any.hpp> 

using boost::any_cast; 
typedef std::map<std::string, boost::any> t_map; 


int main(int argc, char **argv) 
{ 

    t_map map; 
    char *pc = "boo yeah!"; 

    map["a"] = 2.1; 
    map["b"] = pc; 

    cout << "map contents" << endl; 
    cout << any_cast<double>(map["a"]) << endl; 
    cout << any_cast<char*>(map["b"]) << endl; 

    return 0; 
} 
0

提升任何肯定的作品,但我认为使用INT键入技术作为融合图的关键类型是一个更好的解决方案。没有类型的擦除和可能更快