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

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T07:38:39+00:00 2026-05-30T07:38:39+00:00

First, a little background: At my work we bind callbacks to be invoked later,

  • 0

First, a little background: At my work we bind callbacks to be invoked later, which can make trying to follow control flow through the logs quite difficult. To help this, we use a “log context,” which lets you follow a request as it goes through the system. You can copy out the current context with a static function log_context::get_current and restore it with the static function log_context::set_current. This leads to a leads to a lot of repeated code every time we post callbacks to worker queues.

I would like to make a function which is a drop-in replacement for std::bind that will save the current log_context and restore it when invoked. However, I’m having some trouble writing it.

Right now, the function looks like this:

template <typename TResult,
          typename... TFuncArgs,
          typename Func,
          typename... TProvidedArgs
         >
std::function<TResult (TFuncArgs...)>
bind_with_context(const std::function<TResult (TFuncArgs...)>& throwaway,
                  Func func,
                  TProvidedArgs&&... args
                 )
{
    log_context cxt = log_context::get_current();
    auto bound = std::bind(func, std::forward<TProvidedArgs>(args)...);
    auto lambda = [cxt, bound] (TFuncArgs... args) -> TResult
                  {
                      log_context::set_current(cxt);
                      return bound(args...);
                  };
    return lambda;
}

It works, but the problem is the usage requires you to pass the function type for no real reason (aside from that’s how I find out what to use for TFuncArgs):

bind_with_context(func_type(), &some_class::some_func, ptr, _1, "Bob", _2);

So, not quite a drop-in replacement. It seems like one should know this information at compile-time, I just can’t figure out how. It is almost there. How can I eliminate the need to pass in the type of function?


My initial thought was to split the binding from converting it to a function like so:

template <typename Func>
struct context_binder
{
public:
    context_binder(const Func& func) :
            func(func)
    { }

    // Use the casting operator to figure out what we're looking for:
    template <typename TReturn, typename... TFuncArgs>
    operator std::function<TReturn (TFuncArgs...)>() const
    {
        log_context cxt = log_context::get_current();
        auto lambda = [func, cxt] (TFuncArgs... args) -> TReturn
                      {
                          log_context::set_current(cxt);
                          return func(std::forward<TFuncArgs>(args)...);
                      };
        return lambda;
    }

private:
    Func func;
};

template <typename F, typename... TArgs>
auto bind_with_context(F f, TArgs&&... args)
        -> context_binder<decltype(std::bind(f, std::forward<TArgs>(args)...))>
{
    return std::bind(f, std::forward<TArgs>(args)...);
}

The problem is that the cast (operator std::function<TReturn (TFuncArgs...)>() const) will never be called (given int foo(int x, int y, int z)):

std::function<int (int)> f = bind_with_context(&foo, 4, 5, _1);

The reason is that functions constructor is trying to grab operator () from the context_binder (even though it doesn’t have one).

In file included from scratch.cpp:1:0:
/usr/local/include/gcc-4.6.2/functional: In static member function ‘static _Res std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_invoke(const std::_Any_data&, _ArgTypes ...) [with _Res = int, _Functor = context_binder<std::_Bind<int (*(int, int, std::_Placeholder<1>))(int, int, int)> >, _ArgTypes = {int}]’:
/usr/local/include/gcc-4.6.2/functional:2148:6:   instantiated from ‘std::function<_Res(_ArgTypes ...)>::function(_Functor, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type) [with _Functor = context_binder<std::_Bind<int (*(int, int, std::_Placeholder<1>))(int, int, int)> >, _Res = int, _ArgTypes = {int}, typename std::enable_if<(! std::is_integral<_Functor>::value), std::function<_Res(_ArgTypes ...)>::_Useless>::type = std::function<int(int)>::_Useless]’
scratch.cpp:53:85:   instantiated from here
/usr/local/include/gcc-4.6.2/functional:1764:40: error: no match for call to ‘(context_binder<std::_Bind<int (*(int, int, std::_Placeholder<1>))(int, int, int)> >) (int)’

So my question for this almost solution is: Is there any way to get g++ to prefer my cast-out operator instead of trying to use function‘s constructor?

  • 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-05-30T07:38:40+00:00Added an answer on May 30, 2026 at 7:38 am

    The solution is to separate the binding from the converting to an std::function using operator ():

    template <typename Func>
    struct context_binder
    {
    private:
        Func        func;
        log_context cxt;
    
    public:
        context_binder(const Func& func) :
                func(func),
                cxt(log_context::get_current())
        { }
    
        template <typename... TArgs>
        auto operator ()(TArgs&&... args) const
                -> decltype(func(std::forward<TArgs>(args)...))
        {
            log_context::set_current(cxt);
            return func(std::forward<TArgs>(args)...);
        }
    };
    
    template <typename F, typename... TArgs>
    auto bind_with_context(F f, TArgs&&... args)
            -> context_binder<decltype(std::bind(f, std::forward<TArgs>(args)...))>
    {
        return std::bind(f, std::forward<TArgs>(args)...);
    }
    

    The expansion into TArgs happen when someone tries to assign a context_binder to an std::function (whose constructor for non-integral tries to grab operator()).

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

Sidebar

Related Questions

First a little background. The company I work for writes web based software that
First, a little background. The company I work for uses a massive function /
A little background first: I'm designing a web application for a control system that
First a little background, I'm using jdk 1.6. I've got a 2 column table
A little background first. I've been tasked with encrypting files with a Powershell script
A little background first: I'm a designer/developer and decided to use subversion for a
First, a little background: I'm displaying a data set with 288 rows and 8
First, a little background, because there is a lot of interaction going on: I'm
First, a little background. I have strings that resemble the following: ((Foo.Bar.StartsWith(A)) && (Foo.Bar.EndsWith(B)))
First a little background about why I'm asking this question... I'm working on a

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.