3

Is it possible to change this C++11 initialization:

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

To some form with Boost.Assignment without using temporaries? It does not seem possible to nest map_list_of in this way, unfortunately. Am I wrong?

Note: I am prepared for some terrible macros. As long as it works generally enough it would be fine. Variadic templates are not OK, as the target compiler is Intel C++ 2013 and/or MSVS2012.

EDIT: The "ideal" wrapper interface I would like to use looks something like this:

//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...

Where any /*something*/ can be empty. This should use both C++11 brace init or boost::assign::map_list_of. I am trying to avoid a manual repetition like here: https://stackoverflow.com/a/1872506/256138

Community
  • 1
  • 1
rubenvb
  • 74,642
  • 33
  • 187
  • 332

1 Answers1

4

It is possible to nest map_list_of in this manner, with hackery (but there may be temporaries created underneath, I'm unsure of that):

#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";

Possible macro interface (ignoring the empty requirement, mainly because I am unsure what it means):

#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;
}

Admittedly quite verbose but seems to meet your requirement.

See C++11 online demo at http://ideone.com/6Xx2t.

Community
  • 1
  • 1
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • This looks great. You wouldn't know of a way to wrap the boost and C++11 using macros? Won't the braces and recursive macro "calls" cause problems for that? – rubenvb Sep 19 '12 at 13:15
  • @rubenvb, I am unsure what you mean by _using macros_ and _recursive macro "calls"_? – hmjd Sep 19 '12 at 13:17
  • Hmmm... Is there a write-once way to define a macro that takes any number of map elements? It seems to me I need a macro function taking 4 arguments to wrap both boost and C++11. If I need different maps, I'd need to write macros with a matching number of elements, no? – rubenvb Sep 19 '12 at 13:21
  • @rubenvb, could you edit your question with an example of the interface (macro or other) that you seem to need? – hmjd Sep 19 '12 at 13:25
  • I edited it in. I'm not very picky, just worried about the scalability. – rubenvb Sep 19 '12 at 13:39
  • inevitably verbose, but exactly what I am looking for. I thank you very much! – rubenvb Sep 19 '12 at 15:06
  • @hmjd The nesting of boost's map_list_of didn't work for me. Were you able to test it successfully? – chitti Oct 29 '13 at 05:29
  • I concur with chitti; [this does not work](http://coliru.stacked-crooked.com/a/315bbfc8ebee7c97). – Lightness Races in Orbit May 01 '15 at 13:51
  • [Now it does](http://coliru.stacked-crooked.com/a/7ad5967b7383e405) :) /cc @chitti – Lightness Races in Orbit May 01 '15 at 15:41