Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to write a C++ class member function wrapper?

I want to wrap some class member functions and do some preparing and cleaning up work around them.

I try to copy some other thread pool code but get some error I cannot deal out. How to do it correctly?

#include <iostream>
#include <string>
using namespace std;
class A {
public:
    void connect() {};
    void close() {};
    template<typename F, typename ... Args>
    auto wrapper(F&& f, Args&& ... args) -> typename std::result_of<F(Args...)>::type {
        using return_type = typename std::result_of<F(Args...)>::type;
        connect();
        return_type ret = f(args...);
        close();
        return ret;
    }
    bool c(int a, string b) {}
    string c(string b) {return b;}
    bool r(int a, string b) {}
};
int main() {
    A a;
    a.connect();
    a.c(1, "abc");
    a.close(); // equal to a.wrapper(a.c, 1, "abc"); but compling error, how to write it correctly?
    cout << "result of a is: " << a.wrapper(a.c, 1, "abc") ? "successful" : "fail" << endl;
    cout << "result of another a is: " << a.wrapper(a.c, "abc") << endl;
    cout << "result of r is:" << a.wrapper(a.r, 1, "abc") << endl;
}

And I get the error like this:

main.cpp: In function ‘int main()’:
main.cpp:25:58: error: no matching function for call to ‘A::wrapper(<unresolved overloaded function type>, int, const char [4])’
     cout << "result of a is: " << a.wrapper(a.c, 1, "abc") ? "successful" : "fail" << endl;
                                                          ^
main.cpp:25:58: note: candidate is:
main.cpp:9:10: note: template<class F, class ... Args> typename std::result_of<_Functor(_ArgTypes ...)>::type A::wrapper(F&&, Args&& ...)
     auto wrapper(F&& f, Args&& ... args) -> typename std::result_of<F(Args...)>::type {
          ^
main.cpp:9:10: note:   template argument deduction/substitution failed:
main.cpp:25:58: note:   couldn't deduce template parameter ‘F’
     cout << "result of a is: " << a.wrapper(a.c, 1, "abc") ? "successful" : "fail" << endl;
                                                          ^
main.cpp:25:87: error: invalid operands of types ‘const char [5]’ and ‘<unresolved overloaded function type>’ to binary ‘operator<<’
     cout << "result of a is: " << a.wrapper(a.c, 1, "abc") ? "successful" : "fail" << endl;
                                                                                       ^
main.cpp:26:63: error: no matching function for call to ‘A::wrapper(<unresolved overloaded function type>, const char [4])’
     cout << "result of another a is: " << a.wrapper(a.c, "abc") << endl;
                                                               ^
main.cpp:26:63: note: candidate is:
main.cpp:9:10: note: template<class F, class ... Args> typename std::result_of<_Functor(_ArgTypes ...)>::type A::wrapper(F&&, Args&& ...)
     auto wrapper(F&& f, Args&& ... args) -> typename std::result_of<F(Args...)>::type {
          ^
main.cpp:9:10: note:   template argument deduction/substitution failed:
main.cpp:26:63: note:   couldn't deduce template parameter ‘F’
     cout << "result of another a is: " << a.wrapper(a.c, "abc") << endl;



                                                                   ^
like image 706
Liu Weibo Avatar asked May 12 '26 07:05

Liu Weibo


1 Answers

The expression a.c is not really a pointer to a callable member function. &A::c is, but then it needs an instance of A to be called on.

There are two ways to solve this:

  1. Use std::bind. As in std::bind(&A::c, a)

  2. Use a lambda. As in [&a](int i, std::string const& s) { return a.c(i, s); }

like image 82
Some programmer dude Avatar answered May 14 '26 22:05

Some programmer dude