<small id='5KzDa'></small><noframes id='5KzDa'>

  • <tfoot id='5KzDa'></tfoot>
    <i id='5KzDa'><tr id='5KzDa'><dt id='5KzDa'><q id='5KzDa'><span id='5KzDa'><b id='5KzDa'><form id='5KzDa'><ins id='5KzDa'></ins><ul id='5KzDa'></ul><sub id='5KzDa'></sub></form><legend id='5KzDa'></legend><bdo id='5KzDa'><pre id='5KzDa'><center id='5KzDa'></center></pre></bdo></b><th id='5KzDa'></th></span></q></dt></tr></i><div id='5KzDa'><tfoot id='5KzDa'></tfoot><dl id='5KzDa'><fieldset id='5KzDa'></fieldset></dl></div>
          <bdo id='5KzDa'></bdo><ul id='5KzDa'></ul>

      1. <legend id='5KzDa'><style id='5KzDa'><dir id='5KzDa'><q id='5KzDa'></q></dir></style></legend>
      2. C++:嵌套映射

        C++: Nested map(C++:嵌套映射)
        • <small id='v5XeZ'></small><noframes id='v5XeZ'>

            <tbody id='v5XeZ'></tbody>
          • <bdo id='v5XeZ'></bdo><ul id='v5XeZ'></ul>
            <i id='v5XeZ'><tr id='v5XeZ'><dt id='v5XeZ'><q id='v5XeZ'><span id='v5XeZ'><b id='v5XeZ'><form id='v5XeZ'><ins id='v5XeZ'></ins><ul id='v5XeZ'></ul><sub id='v5XeZ'></sub></form><legend id='v5XeZ'></legend><bdo id='v5XeZ'><pre id='v5XeZ'><center id='v5XeZ'></center></pre></bdo></b><th id='v5XeZ'></th></span></q></dt></tr></i><div id='v5XeZ'><tfoot id='v5XeZ'></tfoot><dl id='v5XeZ'><fieldset id='v5XeZ'></fieldset></dl></div>
                <tfoot id='v5XeZ'></tfoot>
                  <legend id='v5XeZ'><style id='v5XeZ'><dir id='v5XeZ'><q id='v5XeZ'></q></dir></style></legend>
                  本文介绍了C++:嵌套映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  定义如下:

                  struct nmap;struct nmap: map>{};

                  下面的最后一行不起作用:

                  The last line below doesn't work:

                  nmap my_map;my_map["a"] = "b";my_map["c"] = 新的 nmap;my_map["c"]["d"] = "e";

                  我需要添加什么才能使其正常工作?

                  What do I need to add, in order for this to work?

                  推荐答案

                  我建议要么选择一个小巧易读的助手:

                  I'd suggest either going for a tiny little readable helper:

                  #include <boost/variant.hpp>
                  #include <map>
                  
                  using std::map;
                  
                  struct nmap;
                  struct nmap: map<std::string, boost::variant<std::string, nmap*>>
                  {
                      typedef boost::variant<std::string, nmap*> Variant;
                      typedef map<std::string, Variant> base;
                  
                      friend nmap&       as_map(Variant& v)       { return *boost::get<nmap*>(v); }
                      friend nmap const& as_map(Variant const& v) { return *boost::get<nmap*>(v); }
                  
                      friend std::string&       as_string(Variant& v)       { return boost::get<std::string>(v); }
                      friend std::string const& as_string(Variant const& v) { return boost::get<std::string>(v); }
                  };
                  
                  int main()
                  {
                      nmap my_map;
                      my_map["a"] = "b";
                      my_map["c"] =  new nmap;
                  
                      as_map(my_map["c"])["d"] = "e";
                  }
                  

                  或者采用递归变体方式.让我画草图:

                  Or go the recursive variant way. Let me sketch:

                  这让 IMO 更优雅:

                  This is IMO more elegant:

                  #include <boost/variant.hpp>
                  #include <map>
                  
                  using nmap  = boost::make_recursive_variant<std::string, std::map<std::string, boost::recursive_variant_> >::type;
                  using map_t = std::map<std::string, nmap>;
                  
                  #include <iostream>
                  static std::ostream& operator<<(std::ostream& os, nmap const& map);
                  
                  int main()
                  {
                      nmap my_map = map_t
                      {
                          { "a", "b" },
                          { "c", map_t
                              {
                                  { "d", "e" },
                                  { "f", map_t
                                      {
                                          { "most nested", "leaf node" },
                                          { "empty", map_t { } },
                                      } },
                              } },
                          };
                  
                      std::cout << my_map;
                  }
                  

                  乍一看这可能看起来更复杂,它实际上有许多重要的优点:

                  At first glance this may look more complicated, but it actually has a number of important advantages:

                  • 不再从不打算继承的类继承
                  • 不再限制根"对象/必须是一个映射(现在它也可以是一个字符串,因此变体更加一致)
                  • 不再有内存泄漏 由于该变体现在实际上负责分配实际的 nmap 实例,因此具有全部价值 -开箱即用的语义.
                  • 允许对树进行惯用的访问,不需要ifs and buts dereferences",例如考虑我们如何做一个快速的&operator<< 的脏实现:

                  • no more inheriting from classes not intended for inheritance
                  • no more limitation that the 'root' object /must/ be a map (it can be a string too now, so the variant is more consistently honoured)
                  • no more memory leaks Due to the fact that the variant now actually takes care of allocating the actual nmap instances, there's full value-semantics out of the box.
                  • allows for idiomatic visiting of the tree, no need for 'ifs and buts dereferences', e.g. consider how we could do a quick & dirty implementation of that operator<<:

                  static std::ostream& operator<<(std::ostream& os, nmap const& map)
                  {
                      struct print : boost::static_visitor<void>
                      {
                          print(std::ostream& os, int indent = 0) : os(os), indent(indent) { }
                  
                          void operator()(map_t const& map) const {
                              os << "{";
                              for(auto& item : map)
                              {
                                  os << "
                  ";
                                  do_indent();
                                  os << "    " << item.first << ": ";
                                  boost::apply_visitor(print(os, indent+4), item.second);
                              }
                              if (!map.empty()) { os << "
                  "; do_indent(); };
                              os << "}";
                          }
                  
                          void operator()(std::string const& str) const {
                              os << str;
                          }
                  
                      private:
                          std::ostream& os;
                          void do_indent() const { for (int n = indent; n>0; --n) os << ' '; }
                          int indent = 0;
                      };
                  
                      boost::apply_visitor(print(os), map);
                      return os;
                  }
                  

                  看到它在coliru上直播

                  See it Live On coliru

                  输出:

                  # g++ -std=c++11 -Wall -pedantic -Wextra main.cpp  && ./a.out
                  
                  {
                      a: b
                      c: {
                          d: e
                          f: {
                              empty: {}
                              most nested: leaf node
                          }
                      }
                  }
                  

                  这篇关于C++:嵌套映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Unable to access non-const member functions of objects in C++ std::set(无法访问 C++ std::set 中对象的非常量成员函数)
                  How should a size-limited stl-like container be implemented?(应该如何实现大小受限的 stl 类容器?)
                  Constructing std::function argument from lambda(从 lambda 构造 std::function 参数)
                  STL BigInt class implementation(STL BigInt 类实现)
                  Sync is unreliable using std::atomic and std::condition_variable(使用 std::atomic 和 std::condition_variable 同步不可靠)
                  Move list element to the end in STL(在 STL 中将列表元素移动到末尾)

                    <small id='cnD9N'></small><noframes id='cnD9N'>

                    <legend id='cnD9N'><style id='cnD9N'><dir id='cnD9N'><q id='cnD9N'></q></dir></style></legend>
                  • <tfoot id='cnD9N'></tfoot>

                          <tbody id='cnD9N'></tbody>
                      • <i id='cnD9N'><tr id='cnD9N'><dt id='cnD9N'><q id='cnD9N'><span id='cnD9N'><b id='cnD9N'><form id='cnD9N'><ins id='cnD9N'></ins><ul id='cnD9N'></ul><sub id='cnD9N'></sub></form><legend id='cnD9N'></legend><bdo id='cnD9N'><pre id='cnD9N'><center id='cnD9N'></center></pre></bdo></b><th id='cnD9N'></th></span></q></dt></tr></i><div id='cnD9N'><tfoot id='cnD9N'></tfoot><dl id='cnD9N'><fieldset id='cnD9N'></fieldset></dl></div>
                          • <bdo id='cnD9N'></bdo><ul id='cnD9N'></ul>