2012-03-30 93 views
15

我初始化map<string, vector<string> >如下:初始化地圖<串,向量<string>>

map <string, vector<string> > dict; 

dict["USA"].push_back("NYC"); 
dict["USA"].push_back("LA"); 
dict["USA"].push_back("Chicago"); 
dict["USA"].push_back("Dallas"); 

dict["India"].push_back("Delhi"); 
dict["India"].push_back("Bombay"); 

dict["Australia"].push_back("Melbourne"); 
dict["Australia"].push_back("Sydney"); 
dict["Australia"].push_back("Adelaide"); 

我覺得這比較麻煩。同樣的事情在tcl做如下是清潔:

array set dict { 
USA {NYC LA Chicago Dallas} 
India {Delhi Bombay} 
Australia {Melbourne Sydney Adelaide} 
} 

是否有一個更清潔的C++初始化方法是什麼?我的編譯器是gcc 3.4.6

+7

在C++ 11中,是的。在GCC 3.4.6中,沒有。 – Pubby 2012-03-30 21:40:20

+2

GCC 3.4.6 ???你真的應該考慮升級到一個更新的編譯器......有一個boost庫來緩解這種類型的初始化,但我不確定它可以用於這樣一箇舊的編譯器(6年幾乎是永恆) – 2012-03-30 22:01:07

回答

6

如果你不害怕使用一些C風格的宏和一些輔助構造,你可能會發現這個略微不太敏感;地圖的初始化在一行中完成;您只需填寫數據(無論如何您都必須填寫)。

#include <iostream> 
#include <map> 
#include <vector> 
#include <string> 
#include <utility> 

using namespace std; 

struct entry { 
    string key; 
    string* vals; 
    size_t nvals; 
}; 
#define NVAL(x) (sizeof(x)/sizeof(x[0])) 

int main(void) { 
    // Create your data 
    string  usa[]  = {"NYC", "LA"}; 
    string  india[] = {"Delhi", "Mumbai"}; 
    entry  dd[] = { 
          {"USA", usa, NVAL(usa)}, 
          {"India", india, NVAL(india)} 
         }; 
    map<string, vector<string> > dict; 

    // initialize the map 
    for(unsigned int i=0; i<NVAL(dd); i++) 
     dict.insert(make_pair(dd[i].key, vector<string>(dd[i].vals, dd[i].vals+dd[i].nvals))); 

    // Verify 
    for(map<string,vector<string> >::const_iterator ptr=dict.begin(); 
     ptr!=dict.end(); ptr++) { 
     cout << ptr->first << ": "; 
     for(vector<string>::const_iterator eptr=ptr->second.begin(); 
      eptr!=ptr->second.end(); eptr++) 
       cout << *eptr << " "; 
     cout << endl; 
    } 
    return 0; 
} 
+0

你的宏可以簡單地用函數模板替換:'template std :: size_t NVAL(T(&)[N]){return N; }'。 – ildjarn 2012-03-30 22:05:31

+0

這確實是一個優雅的解決方案!謝謝! – haavee 2012-03-30 22:19:38

25

初始化在舊的C++中有很多限制。你的代碼實際上並沒有初始化任何東西;它只是在已經初始化的對象上調用了很多成員函數。

在目前的C++(C++ 11),你可以初始化您正確的地圖:

std::map<std::string, std::vector<std::string>> const dict { 
    { "USA", { "NYC", "LA", "Chicago" } }, 
    { "India", { "Delhi", "Bombay" } } 
}; 
+4

哦,上帝,這很漂亮! – innochenti 2012-03-30 21:55:48

+2

這真是太糟糕了,花了他們〜15年來想出它:P – haavee 2012-03-30 22:20:41

+0

哦,和OP說他的編譯器是g ++ 3.4.6,這是非常非常遠C++ 11 - 所以發佈優雅的解決方案,以至於OP不能使用可能不是那種有用的......唉。 – haavee 2012-03-30 22:21:09

8

你能做到這一點,如果C++ 11不可用:

map <string, vector<string> > dict; 

string usa[] = { "NYC" , "LA" , "Chicago" , "Dallas" }; 
dict["USA"] = std::vector<string>(usa,usa+4); 
8

如果您不反對使用Boost.Assign庫並且您使用的是比C++ 11舊的C++,那麼可以這樣做:

#include <boost/assign/list_of.hpp> 
#include <boost/assign/std/vector.hpp> 
#include <map> 
#include <string> 
#include <vector> 

std::map<std::string, vector<std::string> > dict = boost::assign::map_list_of<std::string, std::vector<std::string> > 
    ("USA", boost::assign::list_of<std::string>("NYC")("LA")("Chicago")("Dallas")) 
    ("India", boost::assign::list_of<std::string>("Delhi")("Bombay")) 
; 
相關問題