Getting rid of dynamic polymorphism and classes

Tommi tommitissari at hotmail.com
Wed Nov 14 17:31:18 PST 2012


Here's the duck-typing design pattern they introduce in the video 
(in C++ again, sorry):

#include <conio.h>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>

class SomeShape
{
public:
     SomeShape() = default;
     explicit SomeShape(int volume) {}

     void draw() const
     {
         _cprintf("Drawing SomeShape\n");
     }
};

class OtherShape
{
public:
     OtherShape() = default;
     explicit OtherShape(int x, int y) {}

     void draw() const
     {
         _cprintf("Drawing OtherShape\n");
     }
};

class ShapeInterface
{
public:
     virtual void draw() const = 0;

     virtual ~ShapeInterface() {}
};

template <typename T>
class PolymorphicShape : public ShapeInterface
{
public:
     template <typename ...Args>
     PolymorphicShape(Args&&... args)
         : _shape (std::forward<Args>(args)...)
     {}

     void draw() const override
     {
         _shape.draw();
     }

private:
     T _shape;
};

template <typename T, typename _ = void>
struct is_shape
     : std::false_type
{};

template <typename T>
struct is_shape<T, typename std::enable_if<
     std::is_same<decltype(T().draw()), void>::value
>::type>
     : std::true_type
{};

template <typename T>
auto drawAgain(const T& shape) -> typename std::enable_if<
     is_shape<T>::value
>::type
{
     shape.draw();
}

int main()
{
     std::vector<std::unique_ptr<ShapeInterface>> shapes;

     shapes.emplace_back(new PolymorphicShape<SomeShape>(42));
     shapes.emplace_back(new PolymorphicShape<OtherShape>(1, 2));

     // Dynamic polymorphism:
     shapes[0]->draw(); // Prints: Drawing SomeShape
     shapes[1]->draw(); // Prints: Drawing OtherShape

     // Static polymorphism:
     drawAgain(SomeShape(123));   // Prints: Drawing SomeShape
     drawAgain(OtherShape(2, 4)); // Prints: Drawing OtherShape

     _getch();
     return 0;
}




More information about the Digitalmars-d mailing list