如何使用不同类型的值的地图?

时间:2016-04-06 20:45:11

标签: c++

我需要一个将int作为键和值的映射,它可以是各种类型的对象

std::map<int, differenttypes*> mapping;

并提取像:

这样的对象
 dialog* newDialog = mapping[let]; //let is some int

插入该值,如:

 mapping[let] = newDialog2;

我如何用地图做到这一点?例如,取字符串,int等的不同类型。 也许使用boost :: variant?

3 个答案:

答案 0 :(得分:1)

您可以使用union和&#34;类型标记&#34; (枚举或字符串)表示联合实际持有的内容。让我们假设您想要保存字符串,整数和浮点数:

union valU { float f; int i; char *s; };
enum valE { fl, in, st };
struct variousT { valU val; valE type; };

void print(variousT v)
{
   switch(v.type)
   {
      case fl: printf("%f", v.val.f); break;
      case in:  printf("%d", v.val.i); break;      
      case st:  printf("%s", v.val.s); break;
   }
}

当然print可以是成员函数,variousT中应该有重载的setter,它将标记与值等一起设置。但这是原始机制。

答案 1 :(得分:0)

您可以在地图容器(或您喜欢的任何其他容器)中使用boost提供的any类型 http://www.boost.org/doc/libs/1_60_0/doc/html/any.html

  

boost :: any类支持复制任何值类型,并严格按照其类型安全检查该值的提取。

要获取有关元素类型的特定于实现的信息,请使用boost::any

的以下函数成员
 const std::type_info & type() const;

此处示例(使用std :: list): http://www.boost.org/doc/libs/1_60_0/doc/html/any/s02.html

应该是最安全,最快捷的方法。

答案 2 :(得分:0)

您可以实施自己的&#39; any&#39;输入(使用union中的嵌套struct)并将其存储为地图中的值。但是,像std::string这样的非原始类型在这里有点棘手。

以下是一些基本的例子:

#include <sstream>
#include <algorithm>
#include <string>
#include <map>

struct any {
    enum any_type:char { string_t = 0, int_t = 1 };
    any(){
    }
    any(const any& a) {
        this->type = a.type;
        switch (this->type) {
            case any_type::string_t: new(&(this->str)) std::string(a.str); break;
            case any_type::int_t   : this->i = a.i; break;
            /* more types */
        }
    }
    ~any(){
        switch (this->type) {
            case any_type::string_t: { if (str.size()) { str.std::string::~string(); } } break;  
            /* more types */
            default: ;
        }
    }
    std::string descr() const {
        switch (this->type) {
            case any_type::string_t: { std::stringstream s; s << "string : " << str; return s.str(); }  
            case any_type::int_t   : { std::stringstream s; s << "int    : " << i; return s.str(); }
            /* more types */
        }
    }
    any_type type;
    union {
        std::string str;
        int i;
        /* more types */
    };
};
using any_t = any::any_type;

int main() {
    std::map<std::string,any> m;
    any a;
    a.type = any_t::string_t;
    new(&(a.str)) std::string("aaa");
    //a.str = std::string{"aaa"};
    m.insert({"a",a});

    any b;
    b.type = any_t::int_t;
    b.i = 5;
    m.insert({"b",b});

    for(auto& a : m) {
        std::cout << a.second.descr() << "\n";
    }

    return 0;
}