【问题标题】:Nesting Boost.Assignment `map_list_of`嵌套 Boost.Assignment `map_list_of`
【发布时间】:2012-09-19 10:52:23
【问题描述】:

是否可以更改此 C++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。

编辑:我想使用的“理想”包装界面如下所示:

//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*/ 可以为空。这应该同时使用 C++11 大括号 init 或 boost::assign::map_list_of。我试图避免像这里这样的手动重复:https://stackoverflow.com/a/1872506/256138

【问题讨论】:

    标签: c++ boost c++11 variable-assignment list-initialization


    【解决方案1】:

    可以以这种方式嵌套map_list_ofwith hackery(但可能在下面创建临时对象,我不确定):

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

    可能的宏接口(忽略empty要求,主要是我不确定是什么意思):

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

    诚然相当冗长,但似乎满足您的要求。

    http://ideone.com/6Xx2t 上查看 C++11 在线演示。

    【讨论】:

    • 这看起来很棒。您不知道使用宏包装 boost 和 C++11 的方法吗?大括号和递归宏“调用”不会导致问题吗?
    • @rubenvb,我不确定您所说的使用宏递归宏“调用”是什么意思?
    • Hmmm... 是否有一种只写一次的方式来定义一个需要任意数量的地图元素的宏?在我看来,我需要一个带有 4 个参数的宏函数来包装 boost 和 C++11。如果我需要不同的地图,我需要编写具有匹配数量元素的宏,不是吗?
    • @rubenvb,您能否使用您似乎需要的界面(宏或其他)示例来编辑您的问题?
    • 我编辑进去的。我不是很挑剔,只是担心可扩展性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    相关资源
    最近更新 更多