boost::anyを実装してみる
C++テンプレートテクニック 7-3
boost::anyの話が出てきました。
なんでも格納できるクラスです。
とりあえず本を参考にしながら出来る範囲内で実装してみます。
#include <iostream> using std::cout; using std::endl; class any { private: // 非テンプレート基本クラス struct _any_base { virtual ~_any_base() {} virtual const std::type_info& type () const = 0; virtual _any_base* clone() const = 0; }; // テンプレート派生クラス template<class T> struct _any : public _any_base { T m_value; _any(T value) { m_value = value; } const std::type_info& type () const { return typeid(T); } _any_base* clone () const { return new _any<T>(m_value); } virtual ~_any() {} }; _any_base* m_obj; public: template<class T> any (const T& value) { m_obj = new _any<T>(value); } any (const any& obj) { if ( obj.m_obj ) { m_obj = obj.m_obj->clone(); } else { m_obj = 0; } } any& operator=(const any& obj) { delete m_obj; if ( obj.m_obj ) { m_obj = obj.m_obj->clone(); } else { m_obj = 0; } return *this; } template<class T> any& operator=(const T& value) { delete m_obj; m_obj = new _any<T>(value); return *this; } template<class T> const T& cast() const { return dynamic_cast< _any<T>& >(*m_obj).m_value; } const std::type_info& type () const { return m_obj->type(); } ~any () { delete m_obj; } }; class Foo { public: const char* str() const { return "Foo"; } }; int main () { any a = 10; any b = a; cout << b.type().name() << endl; cout << b.cast<int>() << endl; b = Foo(); cout << b.type().name() << endl; cout << b.cast<Foo>().str() << endl; return 0; }
$ main int 10 class Foo Foo
やっと完成。とはいえほぼ本のままだけど。
typeidやconst周りでいろいろ躓いた。まだまだちゃんと理解してないので精進しなければ。