• <small id='9IH53'></small><noframes id='9IH53'>

        <legend id='9IH53'><style id='9IH53'><dir id='9IH53'><q id='9IH53'></q></dir></style></legend>
        • <bdo id='9IH53'></bdo><ul id='9IH53'></ul>

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

      1. C++ 使用 boost fusion adapt_struct 迭代到嵌套结构域

        时间:2023-08-27
            <tbody id='KCkGm'></tbody>
        1. <i id='KCkGm'><tr id='KCkGm'><dt id='KCkGm'><q id='KCkGm'><span id='KCkGm'><b id='KCkGm'><form id='KCkGm'><ins id='KCkGm'></ins><ul id='KCkGm'></ul><sub id='KCkGm'></sub></form><legend id='KCkGm'></legend><bdo id='KCkGm'><pre id='KCkGm'><center id='KCkGm'></center></pre></bdo></b><th id='KCkGm'></th></span></q></dt></tr></i><div id='KCkGm'><tfoot id='KCkGm'></tfoot><dl id='KCkGm'><fieldset id='KCkGm'></fieldset></dl></div>
          <legend id='KCkGm'><style id='KCkGm'><dir id='KCkGm'><q id='KCkGm'></q></dir></style></legend>
            <bdo id='KCkGm'></bdo><ul id='KCkGm'></ul>
            • <small id='KCkGm'></small><noframes id='KCkGm'>

              <tfoot id='KCkGm'></tfoot>

                  本文介绍了C++ 使用 boost fusion adapt_struct 迭代到嵌套结构域的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  两个stackoverflow 答案 建议使用 fusion adapt_struct 迭代结构字段的方法.这种方法看起来不错.但是,如何迭代到一个本身就是结构体的字段?

                  Two stackoverflow answers suggest the approach using fusion adapt_struct to iterate over struct fields. The approach looks nice. However, how do you iterate into a field which itself is a struct?

                  按照前面的答案,我想出了下面的代码.问题在于代码无法编译的#if 0"子句.作为替代解决方案,我创建了decode()"函数来获取指向目标参数的空指针.这有效,但在编译时丢失了类型信息.有更好的解决方案吗?

                  Following the previous answers, I come up with the code below. The problem is at the "#if 0" clause the code does not compile. As an alternative solution I created "decode()" function to take a void pointer to the target argument. That works, but loses the type information at compile time. Is there a better solution?

                  struct Foo_s { int i; };
                  BOOST_FUSION_ADAPT_STRUCT( Foo_s,  (int, i) )
                  
                  struct Bar_s { int v; Foo_s w; };
                  BOOST_FUSION_ADAPT_STRUCT( Bar_s, (int, v)  (Foo_s, w) )
                  
                  struct AppendToTextBox {
                      template <typename T> void operator()(T& t) const {
                          int status = 0;
                          const char *realname = abi::__cxa_demangle(typeid(t).name(), 0, 0, &status);
                          printf("  typename: %s  value: %s  realname: %s
                  ", typeid(t).name(),
                                 boost::lexical_cast<std::string>(t).c_str(), realname);
                          std::string rn(realname);
                          if ( rn.rfind("_s") == rn.size()-2 ) {
                  #if 0 /* this can not compile */
                              for_each(t, AppendToTextBox());
                  #else
                              decode(&t, rn);
                  #endif
                          }
                      }
                  };
                  
                  void decode(void *f, std::string & intype ) {
                      if ( intype.find("Foo_s") == 0 ) 
                          for_each( *(Foo_s *)f, AppendToTextBox());
                  };
                  
                  int main(int argc, char *argv[]) {
                    Bar_s f = { 2, { 3 } };
                    for_each(f, AppendToTextBox());
                    return 0;
                  }
                  

                  我在 wikipedia 上看到,而不是传递您可以使用的类型字符串intype"typeid 和 dynamic_cast.但这只会是一个很小的改进.我正在寻找一种对 C++ 或 boost 语言设计更内在的解决方案.

                  I have seen on wikipedia instead of passing a type string "intype" you can use typeid and dynamic_cast. But that will only be a minor improvement. I'm looking for a solution that is more intrinsic to C++ or boost language design.

                  推荐答案

                  我做了 您可以在我的博客网站上看到的您想要的示例.在这种情况下,它是一个使用嵌套结构的 JSON 序列化程序.自从我在 Boost.Serialization 库中看到它以来,它使用了更多 Boost"解决方案.(另见下文和在 Coliru 上直播.)

                  I made an example of what you want that you can see at my blog site. In this is case it's a JSON serializer that works with nested structs. It uses a 'more Boost' solution since I saw it in the Boost.Serialization library. (See also below and live on Coliru.)

                  该解决方案使用结构的 Fusion Sequence 适配和一个遍历对象成员(递归)的元函数 - 使用 Boost.TypeTraits 和特定类型的不同特征.

                  The solution uses Fusion Sequence adaptation of structs and a metafunction that walks object members (recursively) - using Boost.TypeTraits and different traits for specific types.

                  你可以看到一个更复杂的googlecode corbasim 项目网站上的相同解决方案示例,用于创建运行时自反 API.

                  You can see a more complex example of the same solution at the site for googlecode corbasim project for creating an run-time reflexive API.

                  看到它在 Coliru 上直播

                  See it Live on Coliru

                  #ifndef JSON_SERIALIZER_HPP
                  #define JSON_SERIALIZER_HPP
                  
                  #include <boost/type_traits.hpp> // is_array, is_class, remove_bounds
                  
                  #include <boost/mpl/eval_if.hpp>
                  #include <boost/mpl/identity.hpp>
                  #include <boost/mpl/next_prior.hpp>
                  
                  #include <boost/fusion/mpl.hpp>
                  #include <boost/fusion/adapted.hpp> // BOOST_FUSION_ADAPT_STRUCT
                  
                  // boost::fusion::result_of::value_at
                  #include <boost/fusion/sequence/intrinsic/value_at.hpp>
                  #include <boost/fusion/include/value_at.hpp>
                  
                  // boost::fusion::result_of::size
                  #include <boost/fusion/sequence/intrinsic/size.hpp>
                  #include <boost/fusion/include/size.hpp>
                  
                  // boost::fusion::at
                  #include <boost/fusion/sequence/intrinsic/at.hpp>
                  #include <boost/fusion/include/at.hpp>
                  
                  namespace json
                  {
                  
                  // Forward
                  template < typename T >
                  struct serializer;
                  
                  namespace detail
                  {
                  
                  namespace iterator
                  {
                  
                  template < typename S, typename N >
                  struct Comma
                  {
                      template < typename Ostream >
                      static inline void comma(Ostream& os)
                      {
                          os << ", ";
                      }
                  };
                  
                  template < typename S >
                  struct Comma< S, typename boost::mpl::prior< typename boost::fusion::result_of::size< S >::type >::type >
                  {
                      template < typename Ostream >
                      static inline void comma(Ostream& os)
                      {
                      }
                  };
                  
                  // Iteracion sobre una estructura
                  template < typename S, typename N >
                  struct StructImpl
                  {
                      // Tipo del campo actual
                      typedef typename boost::fusion::result_of::value_at< S, N >::type current_t;
                      typedef typename boost::mpl::next< N >::type next_t;
                      typedef boost::fusion::extension::struct_member_name< S, N::value > name_t;
                  
                      template < typename Ostream >
                      static inline void serialize(Ostream& os, const S& s)
                      {
                          os << """ << name_t::call() << "": ";
                          ::json::serializer< current_t >::serialize(os, boost::fusion::at< N >(s));
                  
                          // Insert comma or not    
                          Comma< S, N >::comma(os);
                  
                          StructImpl< S, next_t >::serialize(os, s);
                      }
                  };
                  
                  // Fin de la iteracion sobre estructuras.
                  template < typename S >
                  struct StructImpl< S, typename boost::fusion::result_of::size< S >::type >
                  {
                      template < typename Ostream >
                      static inline void serialize(Ostream& os, const S& s)
                      {
                          // Nada que hacer
                      }
                  };
                  
                  // Iterador sobre una estructura. Template fachada.
                  template < typename S >
                  struct Struct : StructImpl< S, boost::mpl::int_< 0 > > {};
                  
                  } // iterator
                  
                  template < typename T >
                  struct array_serializer 
                  {
                      typedef array_serializer< T > type;
                  
                      typedef typename boost::remove_bounds< T >::type slice_t;
                  
                      static const size_t size = sizeof(T) / sizeof(slice_t);
                  
                      template < typename Ostream >
                      static inline void serialize(Ostream& os, const T& t)
                      {
                          os << "[";
                          for(size_t idx=0; idx<size; idx++)
                          {
                              ::json::serializer< slice_t >::serialize(os, t[idx]);
                              if (idx != size-1)
                                  os << ", ";
                          }
                          os << "]";
                      }
                  
                  };
                  
                  template < typename T >
                  struct struct_serializer 
                  {
                      typedef struct_serializer< T > type;
                  
                      template < typename Ostream >
                      static inline void serialize(Ostream& os, const T& t)
                      {
                          os << "{";
                          iterator::Struct< T >::serialize(os, t);
                          os << "}";
                      }
                  };
                  
                  template < typename T >
                  struct arithmetic_serializer 
                  {
                      typedef arithmetic_serializer< T > type;
                  
                      template < typename Ostream >
                      static inline void serialize(Ostream& os, const T& t)
                      {
                          os << t;
                      }
                  };
                  
                  template < typename T >
                  struct calculate_serializer
                  {
                      typedef
                          typename boost::mpl::eval_if< boost::is_array< T >,
                              boost::mpl::identity< array_serializer < T > >,
                          //else
                          typename boost::mpl::eval_if< boost::is_class< T >,
                              boost::mpl::identity< struct_serializer < T > >,
                          //else
                              boost::mpl::identity< arithmetic_serializer < T > >
                          >
                          >::type type;
                  
                  };
                  
                  } // detail
                  
                  template < typename T >
                  struct serializer : public detail::calculate_serializer < T >::type
                  {
                  };
                  
                  
                  } // json
                  
                  #endif // JSON_SERIALIZER_HPP
                  
                  //#include "json.hpp"
                  #include <iostream>
                  
                  struct my_other_struct
                  {
                      int my_other_integer;
                  };
                  
                  struct my_struct
                  {
                      int my_integer;
                  
                      typedef int my_array_t[2];
                      my_array_t my_array;
                  
                      typedef my_other_struct my_other_structs_t[3];
                      my_other_structs_t my_other_structs;
                  };
                  
                  BOOST_FUSION_ADAPT_STRUCT(my_struct, (int, my_integer) (my_struct::my_array_t, my_array) (my_struct::my_other_structs_t, my_other_structs))
                  BOOST_FUSION_ADAPT_STRUCT(my_other_struct, (int, my_other_integer))
                  
                  
                  int main(int argc, char *argv[])
                  {
                      my_struct s1 = my_struct { 1, { 42, -42 }, { { 11 }, { 22 }, { 33 } } };
                  
                      json::serializer< my_struct >::serialize(std::cout, s1);
                  
                      std::cout << std::endl;
                  }
                  

                  这篇关于C++ 使用 boost fusion adapt_struct 迭代到嵌套结构域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:用于应用程序本地部署的 MSVC 2015 通用 CRT 下一篇:如何在 netbeans (linux) 中链接库?

                  相关文章

                  <tfoot id='65e0p'></tfoot>
                1. <i id='65e0p'><tr id='65e0p'><dt id='65e0p'><q id='65e0p'><span id='65e0p'><b id='65e0p'><form id='65e0p'><ins id='65e0p'></ins><ul id='65e0p'></ul><sub id='65e0p'></sub></form><legend id='65e0p'></legend><bdo id='65e0p'><pre id='65e0p'><center id='65e0p'></center></pre></bdo></b><th id='65e0p'></th></span></q></dt></tr></i><div id='65e0p'><tfoot id='65e0p'></tfoot><dl id='65e0p'><fieldset id='65e0p'></fieldset></dl></div>

                  <small id='65e0p'></small><noframes id='65e0p'>

                      <bdo id='65e0p'></bdo><ul id='65e0p'></ul>

                    1. <legend id='65e0p'><style id='65e0p'><dir id='65e0p'><q id='65e0p'></q></dir></style></legend>