2016-04-06 2 views
0

мне нужна карта, которая имеет Int в качестве ключа и значения, которые могут быть различные типы объектовКак получить карту с различными типами значений?

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

и экстракт, что объекты, как:

dialog* newDialog = mapping[let]; //let is some int 

вставить это значение как:

mapping[let] = newDialog2; 

Как мне сделать это с помощью карты? Например, различные типы, чтобы взять строку, int и т. Д. Возможно использование boost :: variant?

+1

Все значения карты должны быть одного и того же типа. Вероятно, вы можете использовать полиморфизм во время выполнения, но вопрос задается слишком общим способом, чтобы дать какой-либо значимый ответ. – SergeyA

+0

Точно как вы его пишете? Или вы хотите, чтобы указатели хранилищ различных типов на одной карте? – Chiel

+0

Мне нужны разные типы *, чтобы быть, например, string, int и т. Д. –

ответ

0

Вы можете использовать тип any, что обеспечивает повышение в карте-контейнере (или любой другой контейнер, который вам нравится) http://www.boost.org/doc/libs/1_60_0/doc/html/any.html

Буст :: любой класс поддерживает копирование любого типа значения и безопасно проверен извлечение этого значения строго против его типа.

Чтобы получить информацию о реализации конкретного о введите элемента с помощью следующей функции члена boost::any

const std::type_info & type() const; 

примера здесь (используя зЬй :: список): http://www.boost.org/doc/libs/1_60_0/doc/html/any/s02.html

Должно быть безопасный и быстрый подход.

+0

Как я могу указать/узнать, какой тип объекта он при извлечении из перечисления? –

+0

@MateuszW boost :: any имеет тип функции-члена(), который возвращает std :: type_info –

1

Вы можете использовать объединение и «тег типа» (перечисление или строку), указывающие, что действительно содержит соединение. Давайте предположим, что вы хотите, чтобы держать струны, Интс и поплавки:

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, которые устанавливают метку вместе со значением и т.д. Но это сырье механизм.

0

Вы можете реализовать собственный тип 'any' (используя вложенный 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; 
} 
+1

. Мне кажется, вам нужно назначить новое размещение/размещение места размещения в строке в конструкторе/деструкторе, поскольку это не делается автоматически для членов объединения – galinette

+0

@ galinette Да, вы были правы, спасибо. Я починил это. Дважды проверили его с помощью [valgrind] (http://valgrind.org/) – cwschmidt

Смежные вопросы