powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Variant по mpl types sequences как член класса - как сделать?
4 сообщений из 4, страница 1 из 1
Variant по mpl types sequences как член класса - как сделать?
    #38547377
LowCoder
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет всем!

Посоветуйте плз. решение. Хочу иметь переменную класса variant по заранее определенной последовательности типов. А затем в main вызвать метод, который вызывает метод каждого объекта, который имеет тип определенный в последовательности типов :).

Сейчас поясню.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
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;
}
...
Рейтинг: 0 / 0
Variant по mpl types sequences как член класса - как сделать?
    #38547389
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LowCoder,
А так?
Код: plaintext
1.
 process3<T>::m_t3.push_back( x ); // FAIL!!! :(( Doesn't work
...
Рейтинг: 0 / 0
Variant по mpl types sequences как член класса - как сделать?
    #38547472
LowCoder
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Это бала опечатка. Проблема решена. Вот какой код работает

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
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;
}




Вывод:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Factory start
Factory entry
Type is = 7worker1
Factory entry
Type is = 7worker2
Worker1 init called
Worker2 init called
...
Рейтинг: 0 / 0
Variant по mpl types sequences как член класса - как сделать?
    #38547792
LowCoder
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я очень извиняюсь но код был не совсем корректный. Дело в том что на каждый вызов функций init, run, stop создаются все новые объекты worker1 worker2 те внутренняя переменная m_t3 не вызывается. А вот и правильное окончательное и бесповоротное решение:


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//
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;
}



Вывод чудо-проги


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
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]




те конструкторы воркеров вызываются только один раз. Думаю такой каркас кому нибудь пригодится
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Variant по mpl types sequences как член класса - как сделать?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]