How to convert a vector of base classes to template based code?

Hi, The following program uses virtual functions. Essentially I need to go through all the pairs in 'v'. Since I have already know what are in v at compile time. I would like to convert the dynamic polymorphism to template. Therefore, the runtime would be better. I think this should be done with the help of boost::mpl. But I'm not sure how to do it. Would you please help me? Thanks, Peng #include <iostream> #include <vector> #include <boost/shared_ptr.hpp> struct shape { virtual void show_me() const = 0; virtual ~shape() { } }; struct square : public shape { void show_me() const { std::cout << "square"; } }; struct circle : public shape { void show_me() const { std::cout << "circle"; } }; struct triangle : public shape { void show_me() const { std::cout << "triangle"; } }; int main() { std::vector<boost::shared_ptr<shape> > v; { boost::shared_ptr<shape> s(new square); v.push_back(s); } { boost::shared_ptr<shape> s(new circle); v.push_back(s); } { boost::shared_ptr<shape> s(new square); v.push_back(s); } { boost::shared_ptr<shape> s(new triangle); v.push_back(s); } for(std::vector<boost::shared_ptr<shape> >::const_iterator it = v.begin(); it != v.end(); ++ it) { for(std::vector<boost::shared_ptr<shape> >::const_iterator it2 = it + 1; it2 != v.end(); ++ it2) { (*it)->show_me(); std::cout << " vs. "; (*it2)->show_me(); std::cout << std::endl; } } }

Do you mean you want your vector to be heterogenous, i.e. containing different types? If so, you can use boost::variant: typedef boost::variant<square, circle, triangle> shape_type; // square, circle, triangle may be unrelated types providing show_me() method std::vector<shape_type> shapes; struct drawer : boost::static_visitor<> { template<typename shape> void operator()(shape &sh) const { sh.show_me(); } }; int main() { shapes.push_back(triangle()); shapes.push_back(circle()); BOOST_FOREACH(std::vector<shape_type>::reference shape, shapes) boost::apply_visitor(drawer(), shape); } 2008/7/10, Peng Yu <pengyu.ut@gmail.com>:
Hi,
The following program uses virtual functions. Essentially I need to go through all the pairs in 'v'.
Since I have already know what are in v at compile time. I would like to convert the dynamic polymorphism to template. Therefore, the runtime would be better. I think this should be done with the help of boost::mpl. But I'm not sure how to do it. Would you please help me?
Thanks, Peng
#include <iostream> #include <vector> #include <boost/shared_ptr.hpp>
struct shape { virtual void show_me() const = 0; virtual ~shape() { } };
struct square : public shape { void show_me() const { std::cout << "square"; } };
struct circle : public shape { void show_me() const { std::cout << "circle"; } };
struct triangle : public shape { void show_me() const { std::cout << "triangle"; } };
int main() { std::vector<boost::shared_ptr<shape> > v; { boost::shared_ptr<shape> s(new square); v.push_back(s); } { boost::shared_ptr<shape> s(new circle); v.push_back(s); } { boost::shared_ptr<shape> s(new square); v.push_back(s); } { boost::shared_ptr<shape> s(new triangle); v.push_back(s); }
for(std::vector<boost::shared_ptr<shape> >::const_iterator it = v.begin(); it != v.end(); ++ it) { for(std::vector<boost::shared_ptr<shape> >::const_iterator it2 = it + 1; it2 != v.end(); ++ it2) { (*it)->show_me(); std::cout << " vs. "; (*it2)->show_me(); std::cout << std::endl; } } } _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Peng Yu <pengyu.ut <at> gmail.com> writes:
Hi,
The following program uses virtual functions. Essentially I need to go through all the pairs in 'v'.
Since I have already know what are in v at compile time. I would like to convert the dynamic polymorphism to template. Therefore, the runtime would be better. I think this should be done with the help of boost::mpl. But I'm not sure how to do it. Would you please help me?
You can use boost::fusion::vector (or boost::tuple) as a container. You can use boost::fusion::for_each to iterate through it (there are other algorithms in fusion of course). #include <iostream> #include <boost/fusion/container/vector.hpp> #include <boost/fusion/algorithm/iteration/for_each.hpp> struct square { void show_me() const { std::cout << "square\n"; } }; struct circle { void show_me() const { std::cout << "circle\n"; } }; struct triangle { void show_me() const { std::cout << "triangle\n"; } }; struct show { template <class T> void operator()(const T& obj) const { obj.show_me(); } }; int main() { using namespace boost::fusion; vector<square, circle, triangle, square> v; for_each(v, show()); } HTH, Roman Perepelitsa.

You can use boost::fusion::vector (or boost::tuple) as a container. You can use boost::fusion::for_each to iterate through it (there are other algorithms in fusion of course). <...> int main() { using namespace boost::fusion; vector<square, circle, triangle, square> v; for_each(v, show()); }
HTH, Roman Perepelitsa.
Correct me if i'm mistaken, but fusion::vector<some_types> contains *one* element of each some_types' type, while std::vector<boost::<variant<some_types> > > contains any number of elements of some_types, right?
participants (3)
-
Igor R
-
Peng Yu
-
Roman Perepelitsa