
Hi Steven, I'm afraid I might need some help again. I try to take as model the example in the doc (http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/...). First problem, it seems that the example has a typo. It will not compile without a :Base in the concept_interface specialization: struct concept_interface< ::foo<T, U,void>, Base, T, Enable> : Base ... Second, the example overload.cpp includes a as_param.hpp which no more exists. But my problem is that I need an overload with 1 and 2 parameters: Test t; any< mpl::vector< foo<_self, int>, foo<_self, int, double>, boost::type_erasure::copy_constructible<> > > x (t); x.foo(1); // calls foo(int) x.foo(1,1.0); // calls foo(int, double) I don't get this to compile, the second foo cannot be found, I suppose the first one hides the second. Thanks in advance, Christophe Here my failed attempt (well, one of them ;-) ): template<class T, class U, class V=void, class Enable=void> struct foo {}; template<class T, class U, class V> struct foo<T,U,V,typename boost::disable_if<boost::is_same<V,void> >::type > { static void apply(T& t, const U& u, const V& v) { t.foo(u,v); } }; template<class T, class U, class V> struct foo<T,U,V,typename boost::enable_if<boost::is_same<V,void> >::type > { static void apply(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) { call(::foo<T, U, void>(), *this, arg); } }; 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) { call(::foo<T, U,V>(), *this, arg,arg2); } }; } } struct Test { void foo(int) { std::cout << "foo(int) called" << std::endl; } void foo(double) { std::cout << "foo(double) called" << std::endl; } void foo(int,double) { std::cout << "foo(int,double) called" << std::endl; } }; int main() { Test t; any< mpl::vector< foo<_self, int>, foo<_self, int, double>, boost::type_erasure::copy_constructible<> > > x (t); x.foo(1); // calls foo(int) x.foo(1,1.0); // calls foo(int, double) return 0; }

AMDG On 02/12/2013 02:59 PM, Christophe Henry wrote:
Hi Steven,
I'm afraid I might need some help again. I try to take as model the example in the doc (http://steven_watanabe.users.sourceforge.net/type_erasure/libs/type_erasure/...).
First problem, it seems that the example has a typo. It will not compile without a :Base in the concept_interface specialization:
struct concept_interface< ::foo<T, U,void>, Base, T, Enable> : Base ...
You are correct. Fixed in svn.
Second, the example overload.cpp includes a as_param.hpp which no more exists.
Fixed. It should be param.hpp.
But my problem is that I need an overload with 1 and 2 parameters:
Test t; any< mpl::vector< foo<_self, int>, foo<_self, int, double>, boost::type_erasure::copy_constructible<> > > x (t); x.foo(1); // calls foo(int) x.foo(1,1.0); // calls foo(int, double)
I don't get this to compile, the second foo cannot be found, I suppose the first one hides the second.
Yep. You need two more specializations.
Here my failed attempt (well, one of them ;-) ):
template<class T, class U, class V=void, class Enable=void> struct foo {};
<snip>
namespace boost { namespace type_erasure {
template<class T, class U, class Base, class Enable> struct concept_interface< ::foo<T, U,void>, Base, T, Enable>;
This specialization (a) will be used for one argument as the first instance of foo.
template<class T, class U, class V, class Base> struct concept_interface< ::foo<T, U,V>, Base, T, typename Base::_fun_defined>;
This specialization (b) will be used for two arguments as the second and subsequent instances of foo. The order in which sibling concepts appear is unspecified. In this case what is actually happening is that foo<_self, int, double> is added first, and neither specialization (a) nor specialization (b) matches. 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>;
} }
<snip>
int main() { Test t; any< mpl::vector< foo<_self, int>, foo<_self, int, double>, boost::type_erasure::copy_constructible<> > > x (t); x.foo(1); // calls foo(int) x.foo(1,1.0); // calls foo(int, double) return 0; }
In Christ, Steven Watanabe

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; }
participants (2)
-
Christophe Henry
-
Steven Watanabe