Home > database >  C : Template binding object and method using lambda expression
C : Template binding object and method using lambda expression

Time:09-20

Due to the fact that std::functional uses heap memory when combining it with an std::bind I wanted to replace the std::bind with a lambda expression but I do not quite know how to do this. Is this even possible?

#include <iostream>
#include <functional>
#include <utility>

template<typename Signature>
class Callback;

template<typename R, typename... Args>
class Callback<R(Args...)> final
{
public:
    Callback() noexcept : mFunc() {}
  
    template<typename Obj, typename Method,
             typename std::enable_if_t<std::is_invocable_r<R, Method, Obj, Args...>::value, int> = 0>
    Callback(Obj& obj, Method method)
    {
       // That does not work
        mFunc = [&obj](Args... args){ return obj.method(args); };
        // mFunc = std::bind(method, obj, std::placeholders::_1, std::placeholders::_1); would work
    }

    R operator()(Args... args) const { return mFunc(args...); }

private:
   std::function<R(Args...)> mFunc;
};

struct Foo
{
   Foo() {}

   void print(int a, int b)
   {
      std::cout << a << b << "\n";
   }
};

int main()
{
   Foo foo;

   Callback<void(int, int)> cb(foo, &Foo::print);

   cb(1,2);
}

Compiler throws the following error message:

main.cpp:19:46: error: expression contains unexpanded parameter pack 'args'
        mFunc = [&obj](Args... args){ return obj.method(args); };
                                             ^          ~~~~
main.cpp:19:19: warning: lambda capture 'obj' is not used [-Wunused-lambda-capture]
        mFunc = [&obj](Args... args){ return obj.method(args); };

CodePudding user response:

If you really want to pass a member function pointer then you need to use syntax for calling the method via a member function pointer:

 mFunc = [&,method](Args...x){ return (obj.*method)(x...);};

However, it would be simpler if you'd accept free callables and let the caller bind the object to a member function if necessary.

  • Related