Search code examples
c++lambdac++17std-functionstdbind

How to use lambdas to use std::function with member functions?


I'm trying to move some global functions inside a class. The current code looks like this:

struct S{};

void f(S* s, int x, double d){}
void g(S* s, int x, double d){}
/*
...
...*/
void z(S* s, int x, double d){}

int main()
{
    function<void(S*, int, double)> fp;
    
    //switch(something)
    //case 1:
        fp = f;
    //case 2:
        fp = g;
    //case n:
        fp = z;
}

Suppose I wanted to update the code above to something like (this code bellow doesn't compile):

#include <iostream>
#include <functional>

using namespace std;

struct S
{
    void f(int x, double d){}
    void g(int x, double d){}
    /*
    ...
    ...*/
    void z(int x, double d){}    

    void method_that_has_some_logic_to_use_the_others_above(int x, double d)
    {
        function<void(int, double)> fp; // How do I have to declare here?
        //switch(something)
        //case 1:
        fp = f; // How can achieve something like this using lambdas here?
    //case 2:
        fp = g;
    //case n:
        fp = z;

        fp(x, d);
    }

};


int main()
{
    S s;
    s.method_that_has_some_logic_to_use_the_others_above(10, 5.0);
}

I've seen some solutions using std::bind but read somewhere to avoid using it and prefer lambdas. I'm using C++17, but I have little experience with lambdas and wasn't able to figure out how to solve it with the examples I've found in other answers.


Solution

  • Member functions require a specific class object to invoke, so you need to do

    function<void(S*, int, double)> fp = &S::f; 
    fp(this, x, d);
    

    Or use lambda to capture a specific class object and invoke its member function internally

    function<void(int, double)> fp = [this](int x, double d) { this->f(x, d); };
    fp(x, d);
    

    Demo