【问题标题】:shorthand syntax for c++ map in map地图中c ++地图的简写语法
【发布时间】:2014-05-12 05:34:00
【问题描述】:

如果我有如下定义:

typedef map<string, Foo> Foo_map_1
typedef map<string, Foo_map_1> Foo_map_2
typedef map<string, Foo_map_2> Foo_map_3
typedef map<string, Foo_map_3> Foo_map_4
typedef map<string, Foo_map_4> Foo_map_5

无论如何我可以概括一下,例如,我可以这样做,

Foo_map<10>

并有一个 10 倍的嵌套地图。我不需要像boost::recursive_wrapper 这样的东西,因为级别的数量总是不变的。

【问题讨论】:

    标签: c++ map


    【解决方案1】:

    即使对于有限的 C++ 元编程能力,这似乎也很容易:

    #include <map>
    #include <string>
    
    template<int N, typename K, typename V>
    struct NMap { typedef std::map<K, typename NMap<N-1, K, V>::type> type; };
    
    template<typename K, typename V>
    struct NMap<1, K, V> { typedef std::map<K, V> type; };
    
    int main(int argc, const char *argv[]) {
        NMap<3, int, std::string>::type m;
        m[1][2][3] = "Test";
        return 0;
    }
    

    【讨论】:

    • 你能解释一下使用2个结构背后的逻辑吗?
    • @sameerkarjatkar:一个是将 N-map 映射到从键到 (N-1)-map 的映射的通用模板。另一个是结束 N=1 情况的递归的模板特化(否则模板递归将是无限的)。需要该结构是因为 C++03 没有“模板 typedef”,而进行这种类型计算的标准解决方法是使用仅包含 typedef 的模板结构。
    • IOW,如果你的编译器是最新的,你就不再需要这些结构了。
    • @MSalters:C++03 的限制并不重要(只需要你添加::type)。 OTOH c++11 别名(据我所知是“解决方案”)不允许部分专业化,在我看来这是一个更严重的问题。
    • @6502:嗯,你可以给部分特化起别名,但你不能部分特化别名。所以你绝对可以给你的NMap&lt;N,K,V&gt;::type 起别名。但是您也有 std::conditional&lt;std::string, typename std::map&lt;N-1, K, V&gt;, (N==1)&gt;::type 可以替换部分专业化。
    【解决方案2】:

    这对我有用。

    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    
    struct Foo
    {
       Foo() : _in(0) {}
       Foo(int in) : _in(in) {}
       int _in;
    };
    
    template <int N> struct Foo_map
    {
       map<string, Foo_map<N-1> > foo_Map;
       Foo_map<N-1>& operator[](string const& key) { return foo_Map[key]; }
    };
    
    template <> struct Foo_map<1>
    {
       map<string, Foo> foo_Map;
       Foo& operator[](string const& key) { return foo_Map[key]; }
    };
    
    int main()
    {
       Foo_map<1> map1;
       map1["abcd"] = Foo(10);
    
       Foo_map<2> map2;
       map2["a"]["b"] = Foo(20);
    
       Foo_map<10> map10;
       map10["a"]["b"]["c"]["d"]["e"]["f"]["g"]["h"]["i"]["j"] = Foo(100);
    
       std::cout << map1["abcd"]._in << std::endl;
       std::cout << map2["a"]["b"]._in << std::endl;
       std::cout << map10["a"]["b"]["c"]["d"]["e"]["f"]["g"]["h"]["i"]["j"]._in << std::endl;
    }
    

    运行程序的输出:

    10 20 100

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2016-09-01
      • 1970-01-01
      相关资源
      最近更新 更多