November 12, 2012
On Monday, 12 November 2012 at 05:49:55 UTC, Tommi wrote:
> Notice that in the video I posted, they introduce a
> similar but cleaner design pattern, that uses virtual functions
> to accomplish the same goal.

I didn't mean to say 'similar', it's rather different. It
accomplishes the same goal though, but using less memory and
through the use of virtual functions.
November 15, 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;
}


November 15, 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;
}


November 15, 2012
Here's the duck-typing design pattern they introduce in the video I posted (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;
}

November 15, 2012
Here's the duck-typing design pattern they introduce in the video
I posted (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;
}

November 15, 2012
Here's the duck-typing design pattern they introduced in the video I posted (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;
}

November 15, 2012
Here's the duck-typing design pattern they intrdouced in the video I posted (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;
}

November 15, 2012
Here's the duck-typing design pattern they intrdouced in the video I posted (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;
}

1 2 3
Next ›   Last »