Creating concept for member template function for use with boost::any in c++ -
i trying create concept use boost::any. concept should class has ha member function signatur void templatefunction(t t). have gotten compile , working fine, 1 type @ time. trying impossible?
#include <iostream> #include <boost/type_erasure/any.hpp> #include <boost/type_erasure/any_cast.hpp> #include <boost/type_erasure/builtin.hpp> #include <boost/type_erasure/operators.hpp> #include <boost/type_erasure/member.hpp> #include <boost/type_erasure/free.hpp> #include <boost/mpl/vector.hpp> #include <boost/any.hpp> using namespace std; namespace mpl = boost::mpl; using namespace boost::type_erasure; class foo { public: template <class t> void templatefunction(t t) { cout << t << endl; } }; template<class c, class t> struct has_template_function { static void apply(c& cont, const t& arg) { cont.templatefunction(arg); } }; namespace boost { namespace type_erasure { template<class c, class t, class base> struct concept_interface<has_template_function<c, t>, base, c> : base { void templatefunction(typename as_param<base, const t&>::type arg) { call(has_template_function<c, t>(), *this, arg); } }; } } int main() { any<has_template_function<_self, int>, _self&> c = foo(); c.templatefunction(5); //compile error: cannot convert parameter 1 'const char [6]' 'const int &' //c.templatefunction("hello"); return 0; }
this kind of possible overloading, , documented in official boost.typeerasure documentation.
the caveat is, said in comments:
you can't type-erase templates , keep polymorphic nature
therefore, have specify overloads explicitly in requirements boost::typeerasure::any type.
you need modify concept interface described in docs, , add string overload requirements section.
your example, modified handle overloads:
#include <iostream> #include <boost/type_erasure/any.hpp> #include <boost/type_erasure/any_cast.hpp> #include <boost/type_erasure/builtin.hpp> #include <boost/type_erasure/operators.hpp> #include <boost/type_erasure/member.hpp> #include <boost/type_erasure/free.hpp> #include <boost/mpl/vector.hpp> #include <boost/any.hpp> #include <string> #include <utility> using namespace std; namespace mpl = boost::mpl; using namespace boost::type_erasure; struct foostruct { template <class t> void templatefunction(t t) { cout << t << endl; } }; template<class t, class u> struct has_template_function { static void apply(t& t, const u& u) { t.templatefunction(u); } }; namespace boost { namespace type_erasure { template<class t, class u, class base, class enable> struct concept_interface< ::has_template_function<t, u>, base, t, enable> : base { typedef void _fun_defined; void templatefunction(typename as_param<base, const u&>::type arg) { call(::has_template_function<t, u>(), *this, arg); } }; template<class t, class u, class base> struct concept_interface< ::has_template_function<t, u>, base, t, typename base::_fun_defined> : base { using base::templatefunction; void templatefunction(typename as_param<base, const u&>::type arg) { call(::has_template_function<t, u>(), *this, arg); } }; } } ostream& operator<<(ostream& os, const std::pair<int, string>& pair) { os << "(" << pair.first << ", " << pair.second << ")"; return os; } int main() { any< mpl::vector < has_template_function<_self, int>, has_template_function<_self, std::string>, has_template_function<_self, std::pair<int,std::string>> > , _self&> c = foostruct(); c.templatefunction(5); c.templatefunction("hello"); c.templatefunction(std::make_pair(5, "hello")); return 0; }
Comments
Post a Comment