Boost logo

Boost :

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;
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk