Вложенность Boost.Assignment `map_list_of`

Можно ли изменить эту инициализацию С++ 11:

const std::map<int, std::map<int, std::string>> test =
  {{1,
    {{1, "bla"},
     {2, "blie"}
    }
   },
   {3,
    {{1, "ha"},
     {2, "hie"}
    }
   }
  };

В какую-то форму с Boost.Assignment без использования временных? К сожалению, вложить map_list_of таким образом не представляется возможным. Я ошибаюсь?

Примечание. Я готов к некоторым ужасным макросам. Пока это работает достаточно в целом, это было бы хорошо. Шаблоны с переменным числом аргументов не подходят, так как целевым компилятором является Intel C++ 2013 и/или MSVS2012.

EDIT: «идеальный» интерфейс оболочки, который я хотел бы использовать, выглядит примерно так:

//header
extern const std::map<int, std::map<int, std::string>> test;

// source file
/*something*/ test
  /*something*/ 1,
  /*something*/ 1, "bla" /*something*/
  /*something*/ 2, "blie" /*something*/
  /*something*/ 2 //etc...

Где любое /*something*/ может быть пустым. Это должно использовать обе скобки С++ 11 init или boost::assign::map_list_of. Я пытаюсь избежать ручного повторения, как здесь: https://stackoverflow.com/a/1872506/256138


person rubenvb    schedule 19.09.2012    source источник


Ответы (1)


Можно вложить map_list_of таким образом, с помощью хакерства (но может быть создано временное ниже, я не уверен в этом):

#include <map>
#include <string>
#include <boost/assign/list_of.hpp>
using boost::assign::map_list_of;

const std::map<int, std::map<int, std::string> > test =
    map_list_of
        (1, map_list_of
            (1, "bla")
            (2, "blie")
            .convert_to_container<std::map<int, std::string> >()
        )
        (3, map_list_of
            (1, "ha")
            (2, "hie")
            .convert_to_container<std::map<int, std::string> >()
        )
    ;

// Correctly prints "hie".
//std::cout << test.find(3)->second.find(2)->second << "\n";

Возможный интерфейс макроса (игнорируя требование пусто, главным образом потому, что я не уверен, что это значит):

#include <iostream>
#include <string>
#include <map>

#ifdef CPP_11_AVAILABLE // Unsure what the actual macro is.
#define map_entries_begin {
#define map_entries_end }
#define map_entry_begin {
#define map_entry_end },

#else
#include <boost/assign/list_of.hpp>
#define map_entries_begin boost::assign::map_list_of
#define map_entries_end
#define map_entry_begin (
#define map_entry_end )

#endif

const std::map<int, std::map<int, std::string>> test =
    map_entries_begin
        //------//
        map_entry_begin
            1, map_entries_begin
                 map_entry_begin 1, "bla" map_entry_end
                 map_entry_begin 2, "blie" map_entry_end
               map_entries_end
        map_entry_end

        //------//
        map_entry_begin
            3, map_entries_begin
                 map_entry_begin 1, "ha" map_entry_end
                 map_entry_begin 2, "hie" map_entry_end
               map_entries_end
        map_entry_end

    map_entries_end;

int main()
{
    std::cout << test.find(3)->second.find(2)->second << "\n";
    return 0;
}

По общему признанию, довольно многословно, но, похоже, соответствует вашему требованию.

См. онлайн-демонстрацию C++11 по адресу http://ideone.com/6Xx2t.

person hmjd    schedule 19.09.2012
comment
Это выглядит великолепно. Вы не знаете, как связать boost и C++11 с помощью макросов? Не вызовут ли для этого проблемы фигурные скобки и рекурсивные вызовы макросов? - person rubenvb; 19.09.2012
comment
@rubenvb, я не уверен, что вы подразумеваете под использованием макросов и рекурсивными вызовами макросов? - person hmjd; 19.09.2012
comment
Хммм... Существует ли способ однократной записи для определения макроса, который принимает любое количество элементов карты? Мне кажется, мне нужна функция макроса, принимающая 4 аргумента, чтобы обернуть как boost, так и C++11. Если мне нужны разные карты, мне нужно написать макросы с соответствующим количеством элементов, не так ли? - person rubenvb; 19.09.2012
comment
@rubenvb, не могли бы вы отредактировать свой вопрос с примером интерфейса (макроса или другого), который вам кажется нужным? - person hmjd; 19.09.2012
comment
Я отредактировал его. Я не очень придирчив, просто беспокоюсь о масштабируемости. - person rubenvb; 19.09.2012
comment
неизбежно многословно, но именно то, что я ищу. Большое спасибо! - person rubenvb; 19.09.2012
comment
@hmjd Вложенность map_list_of boost у меня не сработала. Удалось ли вам успешно протестировать его? - person chitti; 29.10.2013
comment
Я согласен с читти; это не работает. - person Lightness Races in Orbit; 01.05.2015
comment
Теперь это так :) /cc @chitti - person Lightness Races in Orbit; 01.05.2015