MPL类型序列作为类成员的变体 - 如何



请建议,如何解决以下问题 - 我想拥有具有从定义的MPL类型序列的类型的类成员变量boost :: variant类型。之后,我想调用一个方法,该方法调用序列定义的每个类方法的方法.. :)有点复杂,但让我显示:

struct worker1
{
   void init()
   {
      std::cout << "Worker1 init called" << std::endl;
   }
};
struct worker2
{
   void init()
   {
      std::cout << "Worker2 init called" << std::endl;
   }
};
typedef mpl::vector< worker1, worker2> workers;
template< typename U> struct process3
{
   process3()
   {
      factory();
   }
   struct factoryrun
   {
      template< typename T > void operator()(T& x)
      {
         std::cout << "Factory entry" << std::endl;
         std::cout << "Type is = " << typeid( T ).name() << std::endl;
         m_t3.push_back( x ); // FAIL!!! :(( Doesn't work
      }
   };
   struct runinit
   {
      template<typename T> void operator()(T& x)
      {
         x.init();
      }
   };
   void init()
   {
      mpl::for_each<U>( runinit() );
   }
   void factory()
   {
      std::cout << "Factory start" << std::endl;
      mpl::for_each<U>( factoryrun() );
   }
   typedef typename boost::make_variant_over< U >::type types; // FAIL!!! Doesn't work because I need to have variant<worker1, worker2> but not variant<workers>
   static std::vector< boost::variant<types> > m_t;
};
template<typename K> std::vector< boost::variant<K> > process<K>::m_t;
int main() {
   process<workers> prs;
   // Here should be called init() for worker1 and worker2   
   prs.init();
   return 0;
}

问题解决了。这样的代码正在工作

typedef mpl::vector< worker1, worker2> workers;
template< typename U> struct process3
{
   process3()
   {
      factory();
   }
   struct factoryrun
   {
      template< typename T > void operator()(T& x)
      {
         std::cout << "Factory entry" << std::endl;
         std::cout << "Type is = " << typeid( T ).name() << std::endl;
         m_t3.push_back( x );
      }
   };
   struct runinit
   {
      template<typename T> void operator()(T& x)
      {
         x.init();
      }
   };
   void init()
   {
      mpl::for_each<U>( runinit() );
   }
   void factory()
   {
      std::cout << "Factory start" << std::endl;
      mpl::for_each<U>( factoryrun() );
   }
   typedef typename boost::make_variant_over< U >::type types;
   typedef std::vector< boost::variant<types> > Vector; // Make typedef to simplify
   static Vector m_t3;
};
template<typename U> typename process3<U>::Vector process3<U>::m_t3;
int main() {
   process3<workers> prs3;
   prs3.init();
 return 0;
}

输出:

Factory start
Factory entry
Type is = 7worker1
Factory entry
Type is = 7worker2
Worker1 init called
Worker2 init called

我真的很抱歉,但是此代码的第一版不正确。对于初始化的每个呼叫,运行和停止新对象worker1和worker2(每次constructor os os worker1 and worker2都调用)。因此,M_T3变量是没有用的。

波纹管是正确的代码。如您可能看到的,Worker1和Worker2的构造函数被称为一次。

///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
struct worker1
{
   worker1()
   {
      std::cout << "Worker1 ctor" << std::endl;
   }
   void init()
   {
      std::cout << "Worker1 init called. Object address [" << this << "]" << std::endl;
   }
   void run()
   {
      std::cout << "Worker1 run called. Object address [" << this << "]" << std::endl;
   }
   void stop()
   {
      std::cout << "Worker1 stop called. Object address [" << this << "]" << std::endl;
   }
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
struct worker2
{
   worker2()
   {
      std::cout << "Worker2 ctor" << std::endl;
   }
   void init()
   {
      std::cout << "Worker2 init called. Object address [" << this << "]" << std::endl;
   }
   void run()
   {
      std::cout << "Worker2 run called. Object address [" << this << "]" << std::endl;
   }
   void stop()
   {
      std::cout << "Worker2 stop called. Object address [" << this << "]" << std::endl;
   }
};
typedef mpl::vector< worker1, worker2 > workers;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
template< typename U> struct process3
{
   process3()
   {
      factory();
   }
   struct factoryrun
   {
      template< typename T > void operator()(T& x)
      {
         std::cout << "Factory entry" << std::endl;
         std::cout << "Type is = " << typeid( T ).name() << std::endl;
         m_t3.push_back( x );
      }
   };
   void init()
   {
      static init_visitor vis;
      std::for_each( m_t3.begin(), m_t3.end(), boost::apply_visitor( vis ) );
   }
   void run()
   {
      static run_visitor vis;
      std::for_each( m_t3.begin(), m_t3.end(), boost::apply_visitor( vis ) );
   }
   void stop()
   {
      static stop_visitor vis;
      std::for_each( m_t3.begin(), m_t3.end(), boost::apply_visitor( vis ) );
   }
   typedef typename boost::make_variant_over< U >::type types;
   typedef std::vector<types> Vector; // Make typedef to simplify
   static Vector m_t3;
   struct init_visitor: public boost::static_visitor<>
   {
      template <typename T>
      void operator()( T& x )
      {
         std::cout << "Init visitor type=" << typeid(x).name() << std::endl;
         x.init();
       }
   };
   struct run_visitor: public boost::static_visitor<>
   {
     template <typename T>
     void operator()( T& x )
     {
        std::cout << "Run visitor type=" << typeid(x).name() << std::endl;
        x.run();
      }
   };
   struct stop_visitor: public boost::static_visitor<>
   {
     template <typename T>
     void operator()( T& x )
     {
        std::cout << "Stop visitor type=" << typeid(x).name() << std::endl;
        x.stop();
      }
   };
};
template<typename K> typename process3<K>::Vector process3<K>::m_t3;
int main() {
   process3<workers> prs3;
   prs3.init();
   prs3.run();
   prs3.stop();
   return 0;
}

输出:

Factory start
Worker1 ctor
Factory entry
Type is = 7worker1
Worker2 ctor
Factory entry
Type is = 7worker2
Init visitor type=7worker1
Worker1 init called. Object address [0x21bf038]
Init visitor type=7worker2
Worker2 init called. Object address [0x21bf048]
Run visitor type=7worker1
Worker1 run called. Object address [0x21bf038]
Run visitor type=7worker2
Worker2 run called. Object address [0x21bf048]
Stop visitor type=7worker1
Worker1 stop called. Object address [0x21bf038]
Stop visitor type=7worker2
Worker2 stop called. Object address [0x21bf048]

最新更新