Boost.TypeErasure で多重定義の呼び出し
Boost.TypeErasure では any の Concept に複数のシグネチャを定義することで多重定義されているメンバ関数を呼び出すことが出来ます。
BOOST_TYPE_ERASURE_MEMBER を使用した場合はこんな感じです。
[ソース]
#include <boost/type_erasure/any.hpp> #include <boost/type_erasure/member.hpp> #include <boost/mpl/vector.hpp> #include <type_traits> BOOST_TYPE_ERASURE_MEMBER((has_call), call, 1) struct X{ void call(int){ std::cout << "X::call(int)" << std::endl; } void call(float){ std::cout << "X::call(float)" << std::endl; } }; struct sfinae{ template<typename T, typename std::enable_if<std::is_integral<T>{}>::type* = nullptr > void call(T const& t){ std::cout << t << " is integral" << std::endl; } template<typename T, typename std::enable_if<std::is_floating_point<T>{}>::type* = nullptr > void call(T const& t){ std::cout << t << " is floating point" << std::endl; } }; int main(){ namespace te = boost::type_erasure; // int と float 値を受け取る call の定義 typedef te::any< boost::mpl::vector< ::has_call<void(int)>, ::has_call<void(float)>, boost::type_erasure::copy_constructible<> > > any; X x; any any_x(x); any_x.call(42); any_x.call(3.14f); sfinae s; any any_sfinae(s); any_sfinae.call(42); any_sfinae.call(3.14f); return 0; }
[出力]
X::call(int) X::call(float) is integral 42 is floating point 3.14
使い方なんかは any の定義を見てもらえれば何となく分かると思います。
any の定義時に引数型を決定すればいいので、仮想関数では使用できなかった template が使用できるのが大きいですね。
SFINAE なんかも使用することが出来ます。