Boost.TypeErasure で特定の関数で多重定義されているオブジェクトを保持する
さて、Boost.TypeErasure は基本的に保持する型に対してメンバ関数などを要求するのですが、次のように多重定義された関数を呼び出すことで、型に対して非侵入的に Concept を要求する事が出来ます。
[ソース]
#include <boost/type_erasure/any.hpp> #include <boost/type_erasure/builtin.hpp> #include <boost/mpl/vector.hpp> #include <iostream> template<typename T> void disp(T const& t){ std::cout << t << std::endl; } template<typename T = boost::type_erasure::_self> struct displayable{ static void apply(T const& t){ disp(t); } }; void disp(boost::type_erasure::_self){} namespace boost{ namespace type_erasure{ template<typename T, typename Base> struct concept_interface< ::displayable<T>, Base, T> : Base{ void disp() const{ call(::displayable<T>(), *this); } }; } // namespace type_erasure } // namespace boost template<typename Concept, typename T> void disp(boost::type_erasure::any<Concept, T> const& t){ t.disp(); // boost::type_erasure::call(::displayable<>(), t); } #include <string> void disp(std::string const& str){ std::cout << "str :" << str << std::endl; std::cout << "size:" << str.size() << std::endl; } struct X{ X(int value) : value(value){} int value; }; // X のメンバを実装するのではなくて disp 関数をオーバーロードする void disp(X const& x){ std::cout << x.value << std::endl; } int main(){ namespace te = boost::type_erasure; // disp 関数に渡す事が出来る型を保持する typedef te::any< boost::mpl::vector< displayable<>, te::copy_constructible<>, te::relaxed_match > > any_disp; any_disp a(10); disp(a); a = any_disp(std::string("homu")); disp(a); X x(42); a = any_disp(x); disp(a); return 0; }