$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [type_erasure] Overloading
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2013-02-18 15:25:24
Hi Steven,
<snip>
> What you need to add are the following:
> template<class T, class U, class V, class Base, class Enable>
> struct concept_interface< ::foo<T, U,V>, Base, T, Enable>;
> template<class T, class U, class V, class Base, class Enable>
> struct concept_interface< ::foo<T, U,void>, Base, T, typename
> Base::_fun_defined>;
Ok, got it. The compiler still complains about the last version because the 
parameters V and Enable are not used in the class definition but it's easy 
to fix.
In case someone needs it someday or if you want to extend your 
documentation, here the complete code (tested with g++ 4.5 and 4.7.2).
Thanks,
Christophe
#include <boost/type_erasure/concept_interface.hpp>
#include <boost/type_erasure/rebind_any.hpp>
#include <boost/type_erasure/derived.hpp>
#include <boost/type_erasure/is_placeholder.hpp>
#include <boost/type_erasure/constructible.hpp>
#include <boost/type_erasure/relaxed_match.hpp>
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/builtin.hpp>
#include <boost/type_erasure/any_cast.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/vector.hpp>
#include <iostream>
namespace mpl = boost::mpl;
using namespace boost::type_erasure;
template<class T, class U, class V=void>
struct foo
{
    static void apply(const T& t, const U& u, const V& v) { t.foo(u,v); }
};
template<class T, class U>
struct foo<T,U,void>
{
    static void apply(const T& t, const U& u) { t.foo(u); }
};
namespace boost {
namespace type_erasure {
template<class T, class U, class Base, class Enable>
struct concept_interface< ::foo<T, U,void>, Base, T, Enable> : Base
{
    typedef void _fun_defined;
    void foo(typename rebind_any<Base, const U&>::type arg)const
    {
        call(::foo<T, U, void>(), *this, arg);
    }
};
template<class T, class U, class Base>
struct concept_interface< ::foo<T, U,void>, Base, T, typename 
Base::_fun_defined> : Base
{
    using Base::foo;
    void foo(typename rebind_any<Base, const U&>::type arg)const
    {
        call(::foo<T, U,void>(), *this, arg);
    }
};
template<class T, class U, class V, class Base, class Enable>
struct concept_interface< ::foo<T, U,V>, Base, T, Enable> : Base
{
    typedef void _fun_defined;
    void foo(typename rebind_any<Base, const U&>::type arg, typename 
rebind_any<Base, const V&>::type arg2)const
    {
        call(::foo<T, U,V>(), *this, arg,arg2);
    }
};
template<class T, class U, class V, class Base>
struct concept_interface< ::foo<T, U,V>, Base, T, typename 
Base::_fun_defined> : Base
{
    using Base::foo;
    void foo(typename rebind_any<Base, const U&>::type arg, typename 
rebind_any<Base, const V&>::type arg2)const
    {
        call(::foo<T, U,V>(), *this, arg,arg2);
    }
};
}
}
struct Test
{
    void foo(int)const
    {
        std::cout << "foo(int) called" << std::endl;
    }
    void foo(double)const
    {
        std::cout << "foo(double) called" << std::endl;
    }
    void foo(int,double)const
    {
        std::cout << "foo(int,double) called" << std::endl;
    }
};
int main()
{
    Test t;
    any<
        mpl::vector<
            foo<_self, int>,
            foo<_self, int, double>,
            copy_constructible<>
        >
            > x (t);
    x.foo(1);   // calls foo(int)
    x.foo(1,1.0); // calls foo(int, double)
    return 0;
}