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 なんかも使用することが出来ます。