c++ - Calling parametrised method on list items with different template parameters -


i'm trying store , manipulate list of template class objects different parameter types; template class has 2 parametrised methods, 1 returning parameter type , void 1 accepting input.

more specifically, have template class defined follows:

template<typename t> class test { public:     virtual t a() = 0;     virtual void b(t t) = 0; }; 

and different specifications of it, such as:

class testint : public test<int> { public:     int a() {         return 1;     }     void b(int t) {         std::cout << t << std::endl;     } };  class teststring : public test<std::string> { public:     std::string a() {         return "test";     }     void b(std::string t) {         std::cout << t << std::endl;     } }; 

i'd able store in 1 single list different objects of both testint , teststring type , loop through calling 1 method input other, in:

for (auto = list.begin(); != list.end(); ++it)     (*it)->b((*it)->a()); 

i've looked boost::any i'm unable cast iterator specific class, because don't know specific parameter type of each stored object. maybe cannot done in statically typed language c++, wondering whether there way around it.

just sake of completeness, i'll add overall aim develop "parametrised observer", namely being able define observer (as observer pattern) different parameters: test class observer class, while list of different types of observers i'm trying define stored within subject class, notifies them through 2 methods a() , b().

the virtuals have no meaning here, since each t signatures distinct.

so seems have yet version of eternal "how can emulate virtual functions templates" or "how create interface without virtual functions":

the first 1 contains idea employ here.

here's idea of i'd do:

live on coliru

#include <algorithm> #include <iostream>  namespace mytypes {     template <typename t>     struct test {         t a() const;         void b(t t) { std::cout << t << std::endl; }      };      template <> int         test<int>::a()         const { return 1;      }     template <> std::string test<std::string>::a() const { return "test"; }      using testint    = test<int>;     using teststring = test<std::string>; }  #include <boost/variant.hpp>  namespace mytypes {      using value = boost::variant<int, std::string>;      namespace detail {         struct a_f : boost::static_visitor<value> {             template <typename t>             value operator()(test<t> const& o) const { return o.a(); }         };         struct b_f : boost::static_visitor<> {             template <typename t>             void operator()(test<t>& o, t const& v) const { o.b(v); }              template <typename t, typename v>             void operator()(test<t>&, v const&) const {                 throw std::runtime_error(std::string("type mismatch: ") + __pretty_function__);             }         };     }      template <typename o>     value a(o const& obj) {         return boost::apply_visitor(detail::a_f{}, obj);     }      template <typename o, typename v>     void b(o& obj, v const& v) {         boost::apply_visitor(detail::b_f{}, obj, v);     } }  #include <vector>  int main() {     using namespace mytypes;     using anytest = boost::variant<testint, teststring>;      std::vector<anytest> list{testint(), teststring(), testint(), teststring()};      (auto = list.begin(); != list.end(); ++it)         b(*it, a(*it)); } 

this prints

1 test 1 test 

bonus points

if insist, can wrap anytest variant proper class , have a() , b(...) member functions on that:

live on coliru

int main() {     using namespace mytypes;     std::vector<anytest> list{anytest(testint()), anytest(teststring()), anytest(testint()), anytest(teststring())};      (auto = list.begin(); != list.end(); ++it)         it->b(it->a()); } 

Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -