2012-03-30 41 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")) 
; 
相关问题