boost::tuple: iteration mit MPL
-
Ich will folgendes umsetzen:
Klasse A,B,C erben von Base. Base hat die virtuelle Methode foo().
Nun will ich ein template bar<tuple_type> haben, welches für A,B,C foo() aufruft:
menu m; create_menu(boost::tuple<A,B,C>(),m);//template funktion, welche das tuple expandiert, und jeweils foo aufruft. m.Show();
oder anders gesagt:
template<class tuple_type, class parameter> void create_menu(tuple_type t,parameter m){for_each<tuple_type>.foo(m);}
Eigentlich müsste das mit boost::tuple und MPL möglich sein. Nur hab ich gerade keinen Plan, wie das umzusetzen ist.
Also, geht das, und wenn ja wie?
phlox
-
So ich bin was weiter.
element<N, T>::type
und
length<T>::valueergibt zumindest die möglichkeit über alles zu iterieren.
Ähnlich wie hier:
template <int N> struct Factorial { enum { value = N * Factorial<N - 1>::value }; }; template <> struct Factorial<0> { enum { value = 1 }; }; // Factorial<4>::value == 24 // Factorial<0>::value == 1 void foo() { int x = Factorial<4>::value; // == 24 int y = Factorial<0>::value; // == 1 }
Nur möchte ich ja auf die Instanzen zugreifen. Was ja mit get<N> geht.
also ungefähr so:
template<class tuple_type,int N> void do_iterate(tuple_type& t, int i) { t.get<i>().foo(); do_iterate(t,i-1); } template<class tuple_type,0> void do_iterate(tuple_type& t,int i) { t.get<0>().foo(); } template<class tuple_type> void iterate_tuple(tuple_type& t) { do_iterate(t,boost::length<tuple_type>::value); }
Leider klappt das nicht?
Mach ich irgendwo einen Fehler?phlox
-
So, jetzt hab ich es so hingebogen das es klappt:
template<class tuple_type,int N> struct do_iterate { static void call(tuple_type &t) { boost::get<N>(t).foo(); do_iterate<tuple_type, N-1>::call(t); } }; template<class tuple_type> struct do_iterate<tuple_type, 0> { static void call(tuple_type &t) { boost::get<0>(t).foo(); } }; template<class tuple_type> void iterate_tuple(tuple_type &t) { do_iterate<tuple_type, boost::tuples::length<tuple_type>::value -1 >::call(t); }
phlox
-
Hab gerade gesehen, das das auch recht einfach mit boost::fusion geht:
http://spirit.sourceforge.net/dl_more/fusion_v2/libs/fusion/doc/html/fusion/quick_start.html
-
thema war genau was ich gesucht hatte, danke dass du die infos auch weitergibst.