3

Is it possible to bind arguments to a member function call, and later bind the target object separately?

What I was trying to achieve is a helper function which receives a function with arbitrary arguments as an argument, and then executes it on all items in a collection.

void SomeType::Work(UINT a, UINT b, UINT c)
{
    //do something
}

template<typename Function, class Container>
void Execute(const Function& fn, const Container& collection)
{
    for(auto& item : collection)
    {
        auto bound = std::bind(fn, &item);
        bound();
    }
}

void Test()
{
    //eg. container = vector of SomeType
    auto fn = std::bind(&Sometype::Work, 10, 20, 30);
    Execute(fn, container);
}

This was failing with some error within functional:

error C2064: term does not evaluate to a function taking 3 arguments

Eventually pointing at:

see reference to function template instantiation 'void Execute<std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall SomeType::* )(UINT,UINT,UINT),void,SomeType,UINT,UINT,UINT>,UINT &,UINT &,UINT &>>(const Function &)' being compiled
with
[
    Function=std::_Bind<true,void,std::_Pmf_wrap<void (__thiscall SomeType::* )(UINT,UINT,UINT),void,SomeType,UINT,UINT,UINT>,UINT &,UINT &,UINT &>
]

I worked around it by just passing in a lambda that captures the desired values and executes the desired function on an object passed into it. I'm still left wondering if binding functions this way has any legs and I was just going about it wrong, or if it's just not doable.

3
  • where is the definition for Sometype::Work? Commented Aug 8, 2016 at 10:46
  • It was just a function that takes the arguments initially defined. Added an example definition above. Commented Aug 8, 2016 at 10:56
  • Are you attached to bind? I find lambda clearer and has fewer recursive quirks. Commented Aug 8, 2016 at 12:30

2 Answers 2

4

You should leave a placeholder for the target object which will be bound at the 2nd time binding, when bind the member function Sometype::Work().

Try this:

using namespace std::placeholders;
auto fn = std::bind(&Sometype::Work, _1, 10, 20, 30);
                                     ~~

LIVE

Sign up to request clarification or add additional context in comments.

4 Comments

... BTW:, Please, How do you get that fancy box around the LIVE hyperlink? - I am yet to know how to do that in my answers
Interesting, this seems promising. I'll give that a go in a bit
@WhiZ ... but please don't do that. It's a misuse of formatting tags.
This certainly works. Thanks for clearing that up :)
0

It sounds like you simply want to apply a function (with specific arguments) to a collection.

I don't see how that's different than using std::for_each with a specific function.

void Test()
{
    //eg. container = vector of SomeType
    auto fn1 = [/*whatever*/](const container_value_type& obj) { 
        Sometype::Work(10, 20, 30, obj);
    }
    auto fn2 = [/*whatever*/](const container_value_type& obj) { 
        Sometype::Work(40, 50, 60, obj);
    }
    std::for_each(container.begin(), container.end(), fn1);
    std::for_each(container.begin(), container.end(), fn2);
}

4 Comments

Only difference is interface nicety. Not having to duplicate all the for_each and iterator begin.end, etc. That's why I was making the helper, as it was being used in a bunch of functions (container that just forwards all calls to held items), otherwise I would have just used for_each or range based for
OK, so why not use your Execute but instead of using std::bind there, use std::for_each. I mean you bind the item to the function and immediately after you invoke it, so why not just call it and pass the item. IMHO you over-engineer it...
Doesn't answer the question
@ZivS as I mentioned in the post, I did do it differently, by using lambda's and passing that into a function that will do the iteration. I was just curious about std::bind usage

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.