2

I have two classes. One class has a method that takes a function as a parameter and that passed function is expected to have a string as an argument. For example:

class Dog{
public:
    void doDogThings(std::function <void(std::string)> theFunction);

}

class Cat{
public:
    void doCatThings(std::string stringInput);
}

And here they are in action

int main(){
   Cat aCat;
   Dog aDog;
   std::string theString = "Oh jeez";
   aDog.doDogThings(<< insert cat's method and argument here >>);
   .....

This is the part that is fouling me up here; I know I should use

bind(&Cat::doCatThings, ref(aCat) ....?.....);

But I am stuck on how to pass the argument for the Cat method as a parameter to this function pointer. Any help would be greatly be appreciated. Thanks.

1 Answer 1

3

The correct bind syntax would be:

aDog.doDogThings(std::bind(
    &Cat::doCatThings, std::ref(aCat), std::placeholders::_1));

The "placeholder" _1 means "the first argument to the resulting functor will get used here to pass to the bound callable".

But I really don't recommend using std::bind in almost any circumstance. It has some annoying gotchas, is often tricky to get correct, tricky to read again after you've written a use of it, and results in the most terrible compiler errors any time you get something slightly wrong. Lambdas can do anything std::bind can do and quite a bit more, without most of those problems.

So instead, I'd suggest:

aDog.doDogThings(
    [&aCat](std::string stringInput)
    { aCat.doCatThings(std::move(stringInput)); }
);
Sign up to request clarification or add additional context in comments.

4 Comments

So background motivation. I have a couple class managers and I am attempting to limit the amount of the coupling between the classes.I have a client manager that is responsible for managing incoming and outgoing messages and a window manager that displays stuff on screen using ncurses. Shared between the two class managers is a ringbuffer that is used to store ingoing and outgoing messages so that they can be displayed in a window. The window needs to be updated if a) a message is received b) a message is sent.
The goal as to minimize the amount of coupling between the two classes by passing class instances and a corresponding method to trigger updates. When I attempt to adapt your solution it throws an error message. I get the following Parameter type mismatch: Class '__bind<void (ClientManager::*)(string), reference_wrapper<ClientManager>, const placeholders::_1ph<1> &>' is not compatible with class "function<void(string)>' I don't really know if am passing and using the methods correctly at this point because I have never done this kind of thing before.
Not sure what that could mean. Does the little program at coliru.stacked-crooked.com/a/00c817795b7ba652 compile on your system? If you can come up with the shortest possible program that gives you the same error message, that could make a good separate question here.
I got it to work. It was wanting some kind of import and once I did that when I adapted your example it worked exactly as intended.

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.