ゆとりーなの日記

日記的な事を書いて行くと思はれる

継承ナシでコンテナに入った様々なキャラクターを一括描画

twitter上でなんかないの的な空気を感じ取ったので適当に書いてみました。

#include <iostream>
#include <memory>
#include <vector>
#include <pstade/oven/algorithm.hpp>

class character {
 public:
  template <typename T>
  character(const std::shared_ptr<T> &other) : this_(other), vptr_(&vtable_initializer<T>::vtbl_) {}
  void draw() const {
    vptr_->draw(this_.get());
  }
 private:
  struct vtable {
    void (*draw)(void *);
  };
  template <typename T>
  struct vtable_initializer {
    static vtable vtbl_;
    static void draw(void * const self) {
      static_cast<T * const>(self)->draw();
    }
  };
  const std::shared_ptr<void> this_;
  const vtable * const vptr_;
};

template <typename T>
character::vtable character::vtable_initializer<T>::vtbl_ = {
  &character::vtable_initializer<T>::draw
};

struct circle {
  void draw() const {
    std::cout << "○" << std::endl;
  }
};

struct triangle {
  void draw() const {
    std::cout << "△" << std::endl;
  }
};

struct square {
  void draw() const {
    std::cout << "□" << std::endl;
  }
};

int main() {
  std::vector<character> v;
  v.push_back(std::make_shared<circle>());
  v.push_back(std::make_shared<triangle>());
  v.push_back(std::make_shared<square>());
  pstade::oven::for_each(v, [](const character &x) {
    x.draw();
  });
  return 0;
}

まんまType Erasureです。コンテナにぶち込めるようにshared_ptrを使ってみました。

出力:
○
△
□