Boost.TypeErasure でメンバ関数の呼び出しと定義
メンバ関数を呼び出すクラス定義と特殊化を行うことで拡張する事が出来ます。
push_back メンバ関数を呼び出す場合はこんな感じになります。
[ソース]
#include <boost/type_erasure/any.hpp> #include <boost/type_erasure/any_cast.hpp> #include <boost/type_erasure/builtin.hpp> #include <iostream> #include <vector> #include <list> template<typename C, typename T> struct push_back{ static void apply(C& cont, T const& arg){ cont.push_back(arg); } }; namespace boost{ namespace type_erasure{ template<typename C, typename T, typename Base> struct concept_interface< ::push_back<C, T>, Base, C> : Base{ void push_back(typename rebind_any<Base, T const&>::type arg){ call(::push_back<C, T>(), *this, arg); } }; } // namespace type_erasure } // namespace boost int main(){ namespace t = boost::type_erasure; namespace m = boost::mpl; { std::list<int> list; t::any<push_back<t::_self, int>, t::_self&> container(list); int n = 10; t::call(push_back<t::_self, int>(), container, n); std::cout << list.front() << std::endl; } { std::vector<int> v; t::any<push_back<t::_self, int>, t::_self&> container(v); container.push_back(0); container.push_back(1); container.push_back(2); container.push_back(3); container.push_back(4); std::cout << v[0] << std::endl; std::cout << v[1] << std::endl; std::cout << v[2] << std::endl; std::cout << v[3] << std::endl; std::cout << v[4] << std::endl; } return 0; }
[出力]
10 0 1 2 3 4
上記の場合だと push_back の戻り値型を void としているので比較的簡単ですね。
本当は begin や end も定義して range-based for でぶん回したかったんですが、iterator 型を定義するのが手間だったので止めました(ぁ。
しかし、パネェな…。