function + bindを使ったType Erasure


型を消すのはfunctionとbindに任せてしまおうという作戦。

#include <boost/function.hpp>
#include <boost/bind.hpp>

class GameScene {
    boost::function<void()> update_func_;
    boost::function<void()> draw_func_;
public:

    GameScene() {}

    template <class T>
    GameScene(T& obj) :
        update_func_(boost::bind(&T::update, obj)),
        draw_func_(boost::bind(&T::draw, obj)) {}

    template <class T>
    GameScene& operator=(T& obj)
    {
        update_func_ = boost::bind(&T::update, obj);
        draw_func_ = boost::bind(&T::draw, obj);
        return *this;
    }

    void update()
    {
        update_func_();
    }

    void draw() const
    {
        draw_func_();
    }

    bool is_empty() const
    {
        return update_func_.empty() || draw_func_.empty();
    }
};

#include <iostream>
#include <boost/current_function.hpp>

struct Title {
    void update()
    {
        std::cout << BOOST_CURRENT_FUNCTION << std::endl;
    }

    void draw() const
    {
        std::cout << BOOST_CURRENT_FUNCTION << std::endl;
    }
};

struct Game {
    void update()
    {
        std::cout << BOOST_CURRENT_FUNCTION << std::endl;
    }

    void draw() const
    {
        std::cout << BOOST_CURRENT_FUNCTION << std::endl;
    }
};

int main()
{
    GameScene current_scene;

    Title title;
    current_scene = title;
    current_scene.update();
    current_scene.draw();
    
    Game game;
    current_scene = game;
    current_scene.update();
    current_scene.draw();
}
void Title::update()
void Title::draw() const
void Game::update()
void Game::draw() const