1

This question is going to be very much a duplicate, but I've read many of the examples on stack overflow and the common solution is not compiling for me, and I'm trying to figure out why.

So I have a function I want to store in another class, the minimal example of what I'm doing outlined below. It does not compile as this is the issue.

It was working when ParentClass::someFunction only had a single argument, but going to 2, and changing the placeholder to 2 did not work out.

Can someone point out what mistake I am making here?

#include <functional>
#include <string>

class StorageClass{
public:
    //In the actual code it get's passed to another another level 
    //hence why I'm passing by reference rather than value
    void AddFunction(const std::function<void(std::string& a, int b)>& function);

private:
    std::function<void(std::string& a, int b)> callBack;
};


void StorageClass::AddFunction(const std::function<void(std::string& a, int b)>& function){
    callBack = function;
}

class ParentClass {
public:
    ParentClass();
    void someFunction(std::string a, int b);

private:
    StorageClass storageClass;
};

ParentClass::ParentClass() {
    storageClass.AddFunction(std::bind(&ParentClass::someFunction, this, std::placeholders::_2));
}

void ParentClass::someFunction(std::string a, int b) {

}

int main()
{

    ParentClass parentClass;
}
Natio2
  • 235
  • 1
  • 9

2 Answers2

2

Your function has two parameters, so you need two placeholders in your bind expression.

std::bind(&ParentClass::someFunction, this, std::placeholders::_2)

needs to be

std::bind(&ParentClass::someFunction, this, std::placeholders::_1, std::placeholders::_2)

Alternatively you can simplify this with a lambda like

[this](auto a, auto b){ this->someFunction(a, b); }
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • Oh have I misunderstood completely and std::placeholders::_2 isn't saying there are going to be 2 placeholders, but this is the second argument? So if you had 3 arguements it could be std::bind(&ParentClass::someFunction, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)? – Natio2 Sep 03 '22 at 05:06
  • 1
    @Natio2 Exactly that. – NathanOliver Sep 03 '22 at 05:08
  • Awesome =] In the Lambda example, do you replace the whole std::bind with what you have typed? – Natio2 Sep 03 '22 at 05:10
  • 1
    @Natio2 Yep. `storageClass.AddFunction([this](auto a, auto b){ this->someFunction(a, b); });` – NathanOliver Sep 03 '22 at 05:10
  • Ok I am converted now I see the example haha Lambdas are much nicer! Thanks for your time – Natio2 Sep 03 '22 at 05:13
1

You should also pass the first placeholder, not just change _1 to _2.

storageClass.AddFunction(std::bind(&ParentClass::someFunction, this, std::placeholders::_1, std::placeholders::_2));