2014-01-27 111 views
5

我的問題如下:我想將兩個(不多於)不同的數據類型作爲值放入映射中。不同數據類型作爲值的C++映射

typeX A, B, ...; 
typeY Z, Y, ...; 

void func (typeX) { ... } 

void func (typeY) { ... } 


std::map <std::string, what_to_put_here?? >map; 
map["a"] = A; 
map["z"] = Z; 
... 

std::vector<std::string> list; 
//this list will be sth. like "a", "y", ... 

for (unsigned int i = 0; i < list.size(); ++i) 
    func(map[list[i]]) 

很明顯,這不起作用,因爲地圖只接受一種數據類型的值。當循環「list」時,由於map [list [i]]的類型是已知的,因此對「func」的調用應該是明確的。

我想避免顯式類型轉換或類型檢查,即某事像

if (typeid(map[list[i]]).name() == "typeX") 
     func(map[list[i]]) 
    else if (typeid(map[list[i]]).name() == "typeY") 
     func(map[list[i]]) 

你能告訴我,如果這是可能的嗎?同樣,它將僅限於兩種不同的數據類型。謝謝!

+0

我會做的包裝類有兩個成員變量和地圖聲明中使用它。 –

+1

[boost :: variant](http://www.boost.org/doc/libs/1_55_0/doc/html/boost/variant.html)可能會有所幫助。 – user2079303

+1

你有沒有考慮過製作一個公共基類的'typeX'和'typeY'子類? –

回答

3

你想用boost::variant

std::map <std::string, boost::variant<typeX, typeY>> 
+0

謝謝!我試圖使用它,但它在func(map [list [i]])上給我一個錯誤,因爲func()顯然不接受boost :: var。我必須明確地檢查嗎? – user3240855

+0

在調用'func'之前,您必須明確地將對象提取爲正確的類型 –

0

你需要一個type erasure

Type erasure是一種隱藏底層類型的模式,這種已知的例子是boost::any,但請記住,boost有任何動態多態行爲(動態分配在運行時)。另一方面,boost :: variant是另一個例子,它使用模板元編程技術。看到variant vs any

儘管最簡單的解決方案,可以寫一個你自己的類類型擦除與基礎類型的枚舉。

2

typeBase類的typeX和typeY子類是什麼? 如果是這樣,你可以做一個std::map<std::string,typeBase*>在地圖中存儲typeX *和typeY *。

1

使用一些元編程,您可以輕鬆地構建一個異構映射,它可以存儲來自給定類型集合的任何類型。 Here is an example這樣做,沒有類型擦除,也不需要訪問值。

相關問題