Search code examples
c++c++11std-functionstdbind

Using C++ template with std::function and std::bind


I am trying to create a template class which would in turn generate a wrapper over a function. The class will then return the wrapper as result. I would like to use template to have general class that will work with any function with different signatures, such as:

  1. std::function<void()>task = std::bind(fun1, param1, param2);
  2. std::function<int(int, int)>task = std::bind(fun2, param1, param2);

I would like to have something like this:

template <typename T1, typename T2>
class A {
  A (string param1, string param2) {
    // The created wrapper here i.e. 'task' will be returned by the class.
    function<T1>task = bind(T2, param1, param2);
  }

  // Return the created wrapper in the constructor.
  function<T1> returnWrapper() {
    return task;
  }
};

The code above is mostly a pseudo code since it cannot be compiled, but gives an idea about what I am looking for. Is there any solution for this? I think there should be more than simply use a template for a function's signature. Any help would be highly appreciated. I also would like to be able to pass arbitrary number of parameters to 'bind' if possible.


Solution

  • I think I solved the problem! I had to define a class which takes two type names inside a template and pass one of them to std::function as function signature after currying and use the second one in the constructor to define the curried function (result function after wrapping) in std::bind. Then everything worked fine! There might be some better solution, but this was the best and more or less clear solution I got. Here is the got snippet of the solution I found! Hope it helps the other with the same issue:

    #include <iostream>
    #include <functional>
    
    using namespace std;
    
    class A {
      private:
        template <typename T1, typename T2>
        class B { 
          private:
            function<T1>ff;
    
          public:
            B(T2 fun) {
              ff = bind(fun, 1, placeholders::_1);
            }
    
            virtual ~B() {
            }
    
            int exec(int x) {
              return ff(x);
            }
        };
    
        static int myFun(int x, int y) {
          return x + y;
        }
    
      public:
        A() { 
        };
    
        int test() {
          B<int(int), int (*)(int, int)> b(&myFun);
          return b.exec(10);
        }
    
        virtual ~A() {
        };
    };
    
    int main() {
      A a;
    
      // Correct result is '11' since we pass 11 and 1 is in the curried function.
      cout << "test result: " << a.test() << endl;
    
      return 0;
    }