Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 101301
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 11, 20262026-05-11T00:44:40+00:00 2026-05-11T00:44:40+00:00

I want to fill a map with class name and method, a unique identifier

  • 0

I want to fill a map with class name and method, a unique identifier and a pointer to the method.

typedef std::map<std::string, std::string, std::string, int> actions_type; typedef actions_type::iterator actions_iterator;  actions_type actions; actions.insert(make_pair(class_name, attribute_name, identifier, method_pointer));  //after which I want call the appropriate method in the loop  while (the_app_is_running) {     std::string requested_class = get_requested_class();     std::string requested_method = get_requested_method();      //determine class     for(actions_iterator ita = actions.begin(); ita != actions.end(); ++ita)     {         if (ita->first == requested_class && ita->second == requested_method)         {             //class and method match             //create a new class instance             //call method         }     } } 

If the method is static then a simple pointer is enough and the problem is simple, but I want to dynamically create the object so I need to store a pointer to class and an offset for the method and I don’t know if this works (if the offset is always the same etc).

The problem is that C++ lacks reflection, the equivalent code in a interpreted language with reflection should look like this (example in PHP):

$actions = array (      'first_identifier' => array('Class1','method1'),      'second_identifier' => array('Class2','method2'),      'third_identifier' => array('Class3','method3') );  while ($the_app_is_running) {      $id = get_identifier();       foreach($actions as $identifier => $action)      {          if ($id == $identifier)          {              $className = $action[0];              $methodName = $action[1];               $object = new $className() ;               $method = new ReflectionMethod($className , $methodName);              $method -> invoke($object);              }      }  } 

PS: Yes I’m trying to make a (web) MVC front controller in C++. I know I know why don’t use PHP, Ruby, Python (insert your favorite web language here) etc?, I just want C++.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. 2026-05-11T00:44:41+00:00Added an answer on May 11, 2026 at 12:44 am

    I wrote that stuff last hours, and added it to my collection of useful stuff. The most difficult thing is to cope with the factory function, if the types you want to create are not related in any way. I used a boost::variant for this. You have to give it a set of types you ever want to use. Then it will keep track what is the current ‘active’ type in the variant. (boost::variant is a so-called discriminated union). The second problem is how you store your function pointers. The problem is that a pointer to a member of A can’t be stored to a pointer to a member of B. Those types are incompatible. To solve this, i store the function pointers in an object that overloads its operator() and takes a boost::variant:

    return_type operator()(variant<possible types...>) 

    Of course, all your types’ functions have to have the same return type. Otherwise the whole game would only make little sense. Now the code:

    #include <boost/variant.hpp> #include <boost/function.hpp> #include <boost/bind.hpp> #include <boost/tuple/tuple.hpp> #include <boost/mpl/identity.hpp> #include <boost/function_types/parameter_types.hpp> #include <boost/function_types/result_type.hpp> #include <boost/function_types/function_arity.hpp> #include <boost/preprocessor/repetition.hpp> #include <map> #include <string> #include <iostream>  // three totally unrelated classes //  struct foo {     std::string one() {         return 'I ';     } };  struct bar {     std::string two() {         return 'am ';     } };  struct baz {     std::string three() const {         return 'happy!';     } };  // The following are the parameters you have to set //  // return type typedef std::string return_type; // variant storing an object. It contains the list of possible types you // can store. typedef boost::variant< foo, bar, baz > variant_type; // type used to call a function on the object currently active in // the given variant typedef boost::function<return_type (variant_type&)> variant_call_type;  // returned variant will know what type is stored. C++ got no reflection,  // so we have to have a function that returns the correct type based on // compile time knowledge (here it's the template parameter) template<typename Class> variant_type factory() {     return Class(); }  namespace detail { namespace fn = boost::function_types; namespace mpl = boost::mpl;  // transforms T to a boost::bind template<typename T> struct build_caller {     // type of this pointer, pointer removed, possibly cv qualified.      typedef typename mpl::at_c<         fn::parameter_types< T, mpl::identity<mpl::_> >,         0>::type actual_type;      // type of boost::get we use     typedef actual_type& (*get_type)(variant_type&);  // prints _2 if n is 0 #define PLACEHOLDER_print(z, n, unused) BOOST_PP_CAT(_, BOOST_PP_ADD(n, 2)) #define GET_print(z, n, unused)                                         \     template<typename U>                                                \     static variant_call_type get(                                       \         typename boost::enable_if_c<fn::function_arity<U>::value ==     \             BOOST_PP_INC(n), U>::type t                                 \         ) {                                                             \         /* (boost::get<actual_type>(some_variant).*t)(n1,...,nN) */     \         return boost::bind(                                             \             t, boost::bind(                                             \                 (get_type)&boost::get<actual_type>,                     \                 _1) BOOST_PP_ENUM_TRAILING(n, PLACEHOLDER_print, ~)     \             );                                                          \     }  // generate functions for up to 8 parameters BOOST_PP_REPEAT(9, GET_print, ~)  #undef GET_print #undef PLACEHOLDER_print  };  }  // incoming type T is a member function type. we return a boost::bind object that // will call boost::get on the variant passed and calls the member function template<typename T> variant_call_type make_caller(T t) {     return detail::build_caller<T>::template get<T>(t); }  // actions stuff. maps an id to a class and method. typedef std::map<std::string,                   std::pair< std::string, std::string >                  > actions_type;  // this map maps (class, method) => (factory, function pointer) typedef variant_type (*factory_function)(); typedef std::map< std::pair<std::string,      std::string>,                    std::pair<factory_function, variant_call_type>                    > class_method_map_type;  // this will be our test function. it's supplied with the actions map,  // and the factory map std::string test(std::string const& id,                  actions_type& actions, class_method_map_type& factory) {     // pair containing the class and method name to call     std::pair<std::string, std::string> const& class_method =         actions[id];      // real code should take the maps by const parameter and use     // the find function of std::map to lookup the values, and store     // results of factory lookups. we try to be as short as possible.      variant_type v(factory[class_method].first());      // execute the function associated, giving it the object created     return factory[class_method].second(v); }  int main() {     // possible actions     actions_type actions;     actions['first'] = std::make_pair('foo', 'one');     actions['second'] = std::make_pair('bar', 'two');     actions['third'] = std::make_pair('baz', 'three');      // connect the strings to the actual entities. This is the actual     // heart of everything.     class_method_map_type factory_map;     factory_map[actions['first']] =          std::make_pair(&factory<foo>, make_caller(&foo::one));     factory_map[actions['second']] =          std::make_pair(&factory<bar>, make_caller(&bar::two));     factory_map[actions['third']] =          std::make_pair(&factory<baz>, make_caller(&baz::three));      // outputs 'I am happy!'     std::cout << test('first', actions, factory_map)               << test('second', actions, factory_map)               << test('third', actions, factory_map) << std::endl; } 

    It uses pretty fun techniques from boost preprocessor, function types and bind library. Might loop complicated, but if you get the keys in that code, it’s not much to grasp anymore. If you want to change the parameter count, you just have to tweak variant_call_type:

    typedef boost::function<return_type (variant_type&, int)> variant_call_type; 

    Now you can call member functions that take an int. Here is how the call side would look:

    return factory[class_method].second(v, 42); 

    Have fun!


    If you now say the above is too complicated, i have to agree with you. It is complicated because C++ is not really made for such dynamic use. If you can have your methods grouped and implemented in each object you want create, you can use pure virtual functions. Alternatively, you could throw some exception (like std::runtime_error) in the default implementation, so derived classes do not need to implement everything:

    struct my_object {     typedef std::string return_type;      virtual ~my_object() { }     virtual std::string one() { not_implemented(); }     virtual std::string two() { not_implemented(); } private:    void not_implemented() { throw std::runtime_error('not implemented'); } }; 

    For creating objects, a usual factory will do

    struct object_factory {     boost::shared_ptr<my_object> create_instance(std::string const& name) {         // ...     } }; 

    The map could be composed by a map mapping IDs to a pair of class and function name (the same like above), and a map mapping that to a boost::function:

    typedef boost::function<my_object::return_type(my_object&)> function_type; typedef std::map< std::pair<std::string, std::string>, function_type>                    class_method_map_type; class_method_map[actions['first']] = &my_object::one; class_method_map[actions['second']] = &my_object::two; 

    Calling the function would work like this:

    boost::shared_ptr<my_object> p(get_factory().     create_instance(actions['first'].first)); std::cout << class_method_map[actions['first']](*p); 

    Of course, with this approach, you loose flexibility and (possibly, haven’t profiled) efficiency, but you greatly simplify your design.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 58k
  • Answers 58k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • added an answer The -mno-cygwin flag removes all dependencies on Cygwin so that… May 11, 2026 at 8:43 am
  • added an answer You need to look at Context Switching under the Action… May 11, 2026 at 8:43 am
  • added an answer The bottom line is there is no 100% reliable way… May 11, 2026 at 8:43 am

Top Members

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.