2016-04-06 28 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

我想不同類型*爲例如字符串,int等... –

回答

0

你可以使用(你喜歡或任何其他容器)的any類型的提升提供了地圖容器 http://www.boost.org/doc/libs/1_60_0/doc/html/any.html

了boost ::任何類支持任何類型的值複製和安全檢查嚴格按照其類型提取該值。

要獲取有關元素的類型使用boost::any

const std::type_info & type() const; 

例中的下列函數成員在這裏(使用一個std ::列表)執行相關的信息: http://www.boost.org/doc/libs/1_60_0/doc/html/any/s02.html

應該是最安全和最快捷的方法。

+0

當我從枚舉中檢索它時,我將如何投射/知道它是哪種對象類型? –

+0

@MateuszW boost :: any有一個成員函數type(),它返回一個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'類型(在struct中使用嵌套union),並將其作爲值存儲在地圖中。但是,像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

我認爲你需要在構造函數/析構函數的字符串中調用placement new/placement delete,因爲這不會自動爲union成員完成 – galinette

+0

@galinette是的,你說得對,謝謝。我修好了它。雙擊[valgrind](http://valgrind.org/) – cwschmidt

相關問題