Getting rid of dynamic polymorphism and classes

Tommi tommitissari at hotmail.com
Sun Nov 11 21:49:54 PST 2012


On Sunday, 11 November 2012 at 13:24:07 UTC, gnzlbg wrote:
> How would you create a vector of canvas and iterate over them?

I assume you mean to ask "How'd you create a vector of shapes?".
And I assume you mean "... by using the
pointers-to-member-functions design pattern introduced in the
first post". 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 think it's better to use that,
given that virtual function calls aren't noticeably slower than
calling through those member function pointers.

But anyway, here's how you'd do it using the
pointers-to-member-functions idiom:

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

template <int typeId>
class MyShape
{
public:
      void refresh()
      {
          _cprintf("MyShape<%d> refreshed\n", typeId);
      }
};

struct Shape
{
      std::function<void ()> refresh;

      template <typename S, typename _ = typename std::enable_if<
          std::is_same<decltype(S().refresh()), void>::value
      >::type>
      Shape(S&& s)
          : _s (new S(s))
      {
          refresh = [&]()
          { return reinterpret_cast<S*>(_s.get())->refresh(); };
      }

private:
      std::unique_ptr<void> _s; // or std::shared_ptr
};

int main()
{
      std::vector<Shape> shapes;
      shapes.emplace_back(MyShape<2>());
      shapes.emplace_back(MyShape<4>());

      for (auto& shape : shapes)
      {
          shape.refresh();
      }

      _getch();
      return 0;
}

// Prints:
MyShape<2> refreshed
MyShape<4> refreshed


More information about the Digitalmars-d mailing list