Search code examples
c++c++11boostboost-variant

boost::variant and polymorphism in c++11


I am experimenting with polymorphism and boost::variant in c++11

Here is the code

#include <iostream>
#include <boost/variant.hpp>
using namespace std;

class Polygon {
protected:
        int width, height;
public:
        void set_values (int a, int b)
        {
                width=a;
                height=b;
        }
};

class Rectangle: public Polygon {
public:
        Rectangle() {
                std::cout << "ctor rectangle" << std::endl;
        }

        int area()
        {
                return width*height;
        }
};

class Triangle: public Polygon {
public:
        Triangle() {
                std::cout << "ctor triangle" << std::endl;
        }
        int area()
        {
                return width*height/2;
        }
};


int main () {

        Triangle r;
        boost::variant<Rectangle, Triangle> container = r;
        int x = 4;
        int y = 5;
        if (container.type() == typeid(Rectangle)) {
                r.set_values(x,y);
                std::cout << r.area() << std::endl;
        } else if ( container.type() == typeid(Triangle)){
                r.set_values(x,y);
                std::cout << r.area() << std::endl;
        }

        return 0;


}

I am wondering if this is the best way to proceed. There is a repetition in the code (in main() function) where for every type (we get the type at runtime) we execute the same thing, ie set value and print the area.

Is there any better way to do this?


Solution

  • Don't use if-else constructs.

    Take a look at boost. I typed a small and untested example below.

    #include "boost/variant.hpp"
    #include <iostream>
    
    class my_visitor : public boost::static_visitor<void>
    {
    public:
        void operator()(Rectangle const & i) const
        {
            // do something here
        }
    
        void operator()(Triangle const & i) const
        {
            // do something here
        }
    };
    
    int main()
    {
        boost::variant< Triangle, Rectangle > u(Triangle());
        boost::apply_visitor( my_visitor(), u );
    }