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

  • SEARCH
  • Home
  • 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 8152567
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T15:45:03+00:00 2026-06-06T15:45:03+00:00

In my current setup, I have a typedef std::function<void (MyClass&, std::vector<std::string>) MyFunction; std::map<std::string, MyFunction>

  • 0

In my current setup, I have a

typedef std::function<void (MyClass&, std::vector<std::string>) MyFunction;
std::map<std::string, MyFunction> dispatch_map;

And I register my functions in it with a macro. However, I have a problem with this: the parameters are passed as a vector of strings, which I have to convert inside the functions. I would rather do this conversion outside the functions, at the dispatcher level. Is this possible? The function signatures are known at compile time, and never change at run time.

  • 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. Editorial Team
    Editorial Team
    2026-06-06T15:45:04+00:00Added an answer on June 6, 2026 at 3:45 pm

    You can get pretty far with variadic templates and some template/virtual techniques. With the following codes, you’ll be able to do something like:

    std::string select_string (bool cond, std::string a, std::string b) {
        return cond ? a : b;
    }
    
    int main () {
        Registry reg;
        reg.set ("select_it", select_string);
        reg.invoke ("select_it", "1 John Wayne"));
        reg.invoke ("select_it", "0 John Wayne"));
    }
    

    output:

    John
    Wayne
    

    Full implementation:

    These codes are exemplary. You should optimize it to provide perfect forwarding less redundancy in parameter list expansion.

    Headers and a test-function

    #include <functional>
    #include <string>
    #include <sstream>
    #include <istream>
    #include <iostream>
    #include <tuple>
    
    std::string select_string (bool cond, std::string a, std::string b) {
        return cond ? a : b;
    }
    

    This helps us parsing a string and putting results into a tuple:

    //----------------------------------------------------------------------------------
    
    template <typename Tuple, int Curr, int Max> struct init_args_helper;
    
    template <typename Tuple, int Max>
    struct init_args_helper<Tuple, Max, Max> {
        void operator() (Tuple &, std::istream &) {}
    };
    
    template <typename Tuple, int Curr, int Max>
    struct init_args_helper {
        void operator() (Tuple &tup, std::istream &is) {
            is >> std::get<Curr>(tup);
            return init_args_helper<Tuple, Curr+1, Max>() (tup, is);
        }
    };
    
    
    template <int Max, typename Tuple>
    void init_args (Tuple &tup, std::istream &ss)
    {
        init_args_helper<Tuple, 0, Max>() (tup, ss);
    }
    

    This unfolds a function pointer and a tuple into a function call (by function-pointer):

    //----------------------------------------------------------------------------------
    
    template <int ParamIndex, int Max, typename Ret, typename ...Args>
    struct unfold_helper;
    
    template <int Max, typename Ret, typename ...Args>
    struct unfold_helper<Max, Max, Ret, Args...> {
        template <typename Tuple, typename ...Params>
        Ret unfold (Ret (*fun) (Args...), Tuple tup, Params ...params)
        {
            return fun (params...);
        }
    };
    
    template <int ParamIndex, int Max, typename Ret, typename ...Args>
    struct unfold_helper {
        template <typename Tuple, typename ...Params>
        Ret unfold (Ret (*fun) (Args...), Tuple tup, Params ...params)
        {
            return unfold_helper<ParamIndex+1, Max, Ret, Args...> ().
                   unfold(fun, tup, params..., std::get<ParamIndex>(tup));
        }
    };
    
    
    
    template <typename Ret, typename ...Args>
    Ret unfold (Ret (*fun) (Args...), std::tuple<Args...> tup) {
        return unfold_helper<0, sizeof...(Args), Ret, Args...> ().unfold(fun, tup);
    }
    

    This function puts it together:

    //----------------------------------------------------------------------------------
    
    template <typename Ret, typename ...Args>
    Ret foo (Ret (*fun) (Args...), std::string mayhem) {
    
        // Use a stringstream for trivial parsing.
        std::istringstream ss;
        ss.str (mayhem);
    
        // Use a tuple to store our parameters somewhere.
        // We could later get some more performance by combining the parsing
        // and the calling.
        std::tuple<Args...> params;
        init_args<sizeof...(Args)> (params, ss);
    
        // This demondstrates expanding the tuple to full parameter lists.
        return unfold<Ret> (fun, params);
    }
    

    Here’s our test:

    int main () {
        std::cout << foo (select_string, "0 John Wayne") << '\n';
        std::cout << foo (select_string, "1 John Wayne") << '\n';
    }
    

    Warning: Code needs more verification upon parsing and should use std::function<> instead of naked function pointer


    Based on above code, it is simple to write a function-registry:

    class FunMeta {
    public:
        virtual ~FunMeta () {}
        virtual boost::any call (std::string args) const = 0;
    };
    
    template <typename Ret, typename ...Args>
    class ConcreteFunMeta : public FunMeta {
    public:
        ConcreteFunMeta (Ret (*fun) (Args...)) : fun(fun) {}
    
        boost::any call (std::string args) const {
            // Use a stringstream for trivial parsing.
            std::istringstream ss;
            ss.str (args);
    
            // Use a tuple to store our parameters somewhere.
            // We could later get some more performance by combining the parsing
            // and the calling.
            std::tuple<Args...> params;
            init_args<sizeof...(Args)> (params, ss);
    
            // This demondstrates expanding the tuple to full parameter lists.
            return unfold<Ret> (fun, params);
        }
    
    private:
        Ret (*fun) (Args...);
    };
    
    class Registry {
    public:
        template <typename Ret, typename ...Args>
        void set (std::string name, Ret (*fun) (Args...)) {
            funs[name].reset (new ConcreteFunMeta<Ret, Args...> (fun));
        }
    
        boost::any invoke (std::string name, std::string args) const {
            const auto it = funs.find (name);
            if (it == funs.end())
                throw std::runtime_error ("meh");
            return it->second->call (args);
        }
    
    private:
        // You could use a multimap to support function overloading.
        std::map<std::string, std::shared_ptr<FunMeta>> funs;
    };
    

    One could even think of supporting function overloading with this, using a multimap and dispatching decisions based on what content is on the passed arguments.

    Here’s how to use it:

    int main () {
        Registry reg;
        reg.set ("select_it", select_string);
        std::cout << boost::any_cast<std::string> (reg.invoke ("select_it", "0 John Wayne")) << '\n'
                  << boost::any_cast<std::string> (reg.invoke ("select_it", "1 John Wayne")) << '\n';
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

My current setup : I have an entity object with some properties, among them
I have been reviewing the setup of a current Amazon Web Store implementation to
I have a form partial current setup like this to make new blog posts
my current setup is as follows: We have a Linux samba share that contains
Ok, so here's my current setup and my problem at the moment. I have
Here is my current setup. I have two pages running on the jquery mobile
Our current MVC project is set up to have ViewModels that encapsulate the data
Just starting out with subversion, have set up repos for 3 current projects and
My current setup using hibernate uses the hibernate.reveng.xml file to generate the various hbm.xml
The Current Setup: So, I can use the following code to save a file

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.