Boost.TypeErasure のミニマム実装
その昔に書いたコードを発掘したので載せてみるなど。
このコードは Boost.TypeErasure がリリースされた頃に書いたので、現在の実装はまた別のものになっているかも知れない。
[コード]
#include <iostream> #include <boost/any.hpp> template<typename Concept, typename T> struct adapter{ static void apply(boost::any const& any){ Concept::apply(boost::any_cast<T>(any)); } }; template<typename Concept> struct any{ typedef void(*applicative_type)(boost::any const&); template<typename T> any(T const& t) : data(t) , applicative(&adapter<Concept, T>::apply) {} void apply(){ applicative(data); } private: boost::any data; applicative_type applicative; }; struct ostreamable{ template<typename T> static void apply(T const& t){ std::cout << t << std::endl; } }; struct functionable{ template<typename T> static void apply(T const& t){ t(); } }; struct X{ X(int value) : value(value){} void operator ()() const{ std::cout << value << std::endl; } int value; }; std::ostream& operator <<(std::ostream& os, X const& x){ return os << x.value; } int main(){ any<ostreamable> i = 10; i.apply(); X x = 42; any<ostreamable> x_any = x; x_any.apply(); any<functionable> func = [](){ std::cout << "homu" << std::endl; }; func.apply(); any<functionable> x_func = x; x_func.apply(); return 0; }
[出力]
10 42 homu 42
まぁなんというか、なるほどなーというコード。
adapter<Concept, T>::apply
内でキャストを行うことで、any
内からは元の型にはアクセスしなくてもいいような構造になっています。
実際には演算子からの呼び出しや戻り値型も考慮しているのでもっと複雑になってる(はず。
しかし、よくこんなの思いつくよなぁ。