карта инициализации <строка, вектор <string>> - PullRequest
15 голосов
/ 31 марта 2012

Я инициализирую map<string, vector<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

Ответы [ 4 ]

29 голосов
/ 31 марта 2012

Инициализация имела много ограничений в старом C ++.Ваш код фактически ничего не инициализирует;он просто вызывает множество функций-членов для уже инициализированного объекта.

В текущем C ++ (C ++ 11) вы можете правильно инициализировать карту:

std::map<std::string, std::vector<std::string>> const dict {
   { "USA", { "NYC", "LA", "Chicago" } },
   { "India", { "Delhi", "Bombay" }    }
};
9 голосов
/ 31 марта 2012

Если вы не против использования библиотеки Boost.Assign и используете C ++ старше C ++ 11, вы можете сделать это следующим образом:

#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"))
;
8 голосов
/ 31 марта 2012

Вы можете сделать это, если C ++ 11 недоступен:

map <string, vector<string> > dict;

string usa[] = { "NYC" , "LA" , "Chicago" , "Dallas" };
dict["USA"] = std::vector<string>(usa,usa+4);
7 голосов
/ 31 марта 2012

Если вы не боитесь использовать немного макросов в стиле 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;
}
...