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 9044759
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T11:04:13+00:00 2026-06-16T11:04:13+00:00

( Note: As should already be clear from the tags, this is strictly C++03.

  • 0

(Note: As should already be clear from the tags, this is strictly C++03. Yes, I know, lambda makes all this pain go away (and brings in new kinds, I bet), but this is an embedded system, with an OS version from the 90s, and I am told I should be glad I have a C++03 compiler (GCC4.1.x, BTW), or a C++ compiler at all. So please abstain from posting C++11 solutions. No need to rub it in, really.
Also, std::bind(), std::function() etc. are, of course, actually in std::tr1, but I edited out the tr1 prefix, because I thought it adds mostly only noise to the code.
)

I have some server-like thing that I need to register functions with and I need to adapt them to call some object’s similar, but slightly different, functions. These functions have different argument lists. The server “knows” that and when I try to register a function it only accepts one with the correct signature (as correct as std::function requires, that is), depending on some magic tag passed in as a template argument.

Here’s a sketch of the code:

// this I just use
class server {
public:
    template<unsigned int MagicTag>
    bool register_call(typename some_traits_type<MagicTag>::func_type);
};

// this needs to be called from the server
class X {
public:
    bool foo();
    bool bar(std::string&);
    bool baz(int);
};

// this is the glue
class Y {
public:
    Y(X& x) : x_(x) {
        register_call<MAGIC_FOO>(&Y::foo    );
        register_call<MAGIC_BAZ>(&Y::bar, _1);
        register_call<MAGIC_FBZ>(&Y::baz, _1);
    }

private:
    X&                    x_;

    template<unsigned int MagicTag, typename Function>
    bool register_call(Function function) {
        somewhere->register_call<MagicTag>(std::bind( function
                                                    , this ));
    }
    template<unsigned int MagicTag, typename Function, typename PlaceHolder1>
    bool register_call(Function function, PlaceHolder1 place_holder1) {
        somewhere->register_call<MagicTag>(std::bind( function
                                                    , this
                                                    , place_holder1 ));
    }

    int foo()               {return x_.foo()  ? MAGIC_OK : MAGIC_FAILED;}
    int bar(std::string& s) {return x_.bar(s) ? MAGIC_OK : MAGIC_FAILED;}
    int baz(int i)          {return x_.baz(i) ? MAGIC_OK : MAGIC_FAILED;}
};

This actually works, but in reality there are way more functions and doing this as a tedious copy’n’paste effort insults my sense of dignity and produces smelly code. Since all these functions do exactly the same, with the only difference being the function they call and the arguments they have, or do not have, to pass, I should be able to fold them into one parametrized function, hiding the differences behind std::bind(). Failing this, I settled on first doing this for all the functions without any parameters (as in foo()), which is the overwhelming majority.

So I wanted to route all the calls of foo()-like function in X through a single function Y::call_it that does the tedious part:

int call_it(std::function<bool()> f) {return f() ? MAGIC_OK : MAGIC_FAILED;}

and bind the appropriate function in X as an argument to it:

register_call<MAGIC_FOO>(&X::foo); // note the X!

// (this is wrong)
somewhere->register_call<MagicCode>( std::bind( std::bind( &Y::call_it
                                                         , this
                                                         , function )
                                              , std::ref(x_) );

Obviously, this is wrong, and so are all my other attempts at solving this. (I have only been playing with std::bind() for 10 weeks now, so please bear with me). In the end I got lost in an incredible maze of hilarious error messages out of std::function‘s templatized guts that can bring a grown man down in tears and should feed a shrink and his extended family for a year at least.

So before I kill myself out of sheer frustration and orphan my kids — how can I do this?

  • 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-16T11:04:15+00:00Added an answer on June 16, 2026 at 11:04 am

    From what I gather, you want to call Y::call_it() with a std::function object appropriately bound. Given that your inner function takes different numbers of arguments, it is necessary to create a std::function<bool()> generator for the cases where additional arguments are being passed. Assuming the X object can be bound at registration time, registration of a member function without additional arguments is straight forward:

    template <int Magic, typename RC>
    void register_call(RC (X::*member)()) {
        somewhere->register_call<Magic>(
            std::bind(&Y::call_it, this,
                 std::function<bool()>(std::bind(member,
                                                 std::ref(this->x_)))));
    }
    

    When passing one or more arguments, it is necessary to create a std::function<bool()> object upon call time because the additional argument needs to be bound. I don’t think that this can be done without a helper function but it can be done with one helper function per number of arguments:

    template <typename RC, typename Arg0>
    static std::function<bool()>
    bind_argument(RC (X::*member)(Arg0), X& x, Arg0 const& arg0) {
        return std::bind(member, std::ref(x), arg0);
    }
    template <int Magic, typename RC,
              typename Arg0, typename PlaceHolder>
    void register_call(RC (X::*member)(Arg0), PlaceHolder pc) {
        somewhere->register_call<Magic>(
            typename some_traits_type<Magic>::type(
                std::bind(&Y::call_it, this,
                          std::bind(&bind_argument<RC, Arg0>, member,
                                    std::ref(this->x_), pc))));
    }
    

    The helper function creates a function with an additional argument being bound. Note that the function being bound is constructed to be of the same type as the one expected by the register function: This is necessary, e.g., to create a function taking additional, ignored, arguments.

    Below is a test program I used to see if things compile. I don’t have a C++2003 compiler with TR1 at hand and have compiled the code with a C++2011 compiler. However, I don’t think I have used any of the C++2011 extension which isn’t available from C++2003 with TR1.

    #include <functional>
    
    enum {
        MAGIC_OK,
        MAGIC_FAILED,
        MAGIC_FOO,
        MAGIC_BAR,
        MAGIC_FBZ,
        MAGIC_BAZ
    };
    
    template <int> struct server_traits;
    template <> struct server_traits<MAGIC_FOO> {
        typedef std::function<bool()> type;
    };
    template <> struct server_traits<MAGIC_BAR> {
        typedef std::function<bool(std::string&)> type;
    };
    template <> struct server_traits<MAGIC_FBZ> {
        typedef std::function<bool(long)> type;
    };
    template <> struct server_traits<MAGIC_BAZ> {
        typedef std::function<bool(std::string, long)> type;
    };
    
    
    // this I just use
    class server {
    public:
        template<unsigned int MagicTag>
        bool register_call(typename server_traits<MagicTag>::type) {
            return true;
        }
    };
    
    server  s;
    server* somewhere = &s;
    
    // this needs to be called from the server
    class X {
    public:
        bool foo() { return true; }
        bool bar(std::string&) { return true; }
        bool baz(int) { return true; }
    };
    
    // this is the glue
    class Y {
    public:
        Y(X& x) : x_(x) {
            register_call<MAGIC_FOO>(&X::foo    );
            register_call<MAGIC_BAR>(&X::bar, std::placeholders::_1);
            register_call<MAGIC_FBZ>(&X::baz, std::placeholders::_1);
            register_call<MAGIC_BAZ>(&X::baz, std::placeholders::_2);
        }
    
    private:
        X& x_;
    
        int call_it(std::function<bool()> f) {
            return f() ? MAGIC_OK : MAGIC_FAILED;
        }
    
        template <int Magic, typename RC>
        void register_call(RC (X::*member)()) {
            somewhere->register_call<Magic>(
                std::bind(&Y::call_it, this,
                     std::function<bool()>(std::bind(member,
                                                     std::ref(this->x_)))));
        }
        template <typename RC, typename Arg0>
        static std::function<bool()>
        bind_argument(RC (X::*member)(Arg0), X& x, Arg0 const& arg0) {
            return std::bind(member, std::ref(x), arg0);
        }
        template <int Magic, typename RC,
                  typename Arg0, typename PlaceHolder>
        void register_call(RC (X::*member)(Arg0), PlaceHolder pc) {
            somewhere->register_call<Magic>(
                typename server_traits<Magic>::type(
                    std::bind(&Y::call_it, this,
                              std::bind(&bind_argument<RC, Arg0>, member,
                                        std::ref(this->x_), pc))));
        }
    };
    
    int main()
    {
        X x;
        Y y(x);
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Note: Not sure if this is the right stack, please tell if I should
I know there are already articles that covered this, but I'm having an issue
--- Note to moderators: Today (July 15), I've noticed that someone already faced this
[edit] I should note that I need to do this on a live production
Note: I'm using Google Chrome Currently I have this test page http://www.evecakes.com/doodles/canvas_size_issue.htm It should
Anyone has implemented like the below carousel ? Note: The list of items should
Note, this is not a duplicate of .prop() vs .attr() ; that question refers
(Note: This is not a question about what is the best way with code
NOTE: This is a followup to my question here. I have a program that
NOTE: This is an old question and the answers here no longer works (since

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.