Howto use non-static member function for template argument?

Viewed 73

I have this minimal sample code:

#include <functional>
#include <iostream>
#include <vector>


template<class ReadFileCallback>
void fileMgr_ReadWithCallback(std::string filename, ReadFileCallback callback) {
    callback("OK");
}

void globalReadResult(std::string result) {
    std::cout << "ReadResult in global function: result=" << result << std::endl;
}

class MyClass {
public:
  MyClass() {};
  ~MyClass() {};
  
  void Read() {
    fileMgr_ReadWithCallback("file", globalReadResult);
    //fileMgr_ReadWithCallback("file", this->ReadResult);
  }
  
  void ReadResult(std::string result) {
    std::cout << "ReadResult in member function: result=" << result << std::endl;
  }
};

int main()
{
    MyClass c;
    c.Read();
    
    return 0;
}

For callback function I'd like to use a non-static class member MyClass::ReadResult. It would also be good to know before calling the callback if the object is still valid (non-destructed), because otherwise the program will fail I guess.

How shall I change this code to be able to use the MyClass object's ReadResult as callback?

2 Answers

You can just wrap it into a lambda:

class MyClass {
public:
  MyClass() {};
  ~MyClass() {};
  
  void Read() {
    fileMgr_ReadWithCallback("file", [this](const std::string& result){ this->ReadResult(result); });
  }
  
  void ReadResult(std::string result) {
    std::cout << "ReadResult in member function: result=" << result << std::endl;
  }
};

You may use std::bind.

#include <functional>
#include <iostream>
#include <vector>
#include <functional>


template<class ReadFileCallback>
void fileMgr_ReadWithCallback(std::string filename, ReadFileCallback callback) {
    callback("OK");
}

void globalReadResult(std::string result) {
    std::cout << "ReadResult in global function: result=" << result << std::endl;
}

class MyClass {
    public:
        MyClass() {};
        ~MyClass() {};

        void Read() {

            using std::placeholders::_1;
            //std::function<void(std::string)> func = std::bind( &MyClass::ReadResult, this, _1);
            auto func = std::bind( &MyClass::ReadResult, this, _1);
            

            fileMgr_ReadWithCallback("file", func);

            //
            // or
            // fileMgr_ReadWithCallback("file", std::bind( &MyClass::ReadResult, this, _1));
        }  

        void ReadResult(std::string result) {
            std::cout << "ReadResult in member function: result=" << result << std::endl;
        }  
};

int main()
{
    MyClass c; 
    c.Read();


    return 0; 
}

Related