Search code examples
c++std-function

Can we take template types like the std::function does in our custom classes


I was learning some basic cpp and I found out that we can pass lambda functions to a function accepting a std::function like below:

int someFunction(std::function<int(int, int)> sum) {
  return sum(1,3);
}

I was confused as to how the std::function is taking template types as "int(int, int)" generally I have only see classes taking types like someClass<int, int>.

How do we define classes that take the template types like "int(int, int)"?

I tried declaring classes like

template<typename A(typename B)> // --> this just gives an syntax error.
class SomeClass {};

Solution

  • At first, your example should not compile.

    int someFunction(std::function<int(int)> sum) {
      return sum(1,3);
    }
    
    /*
    std::function<int(int)>
                  ^    ^
                  |    |
               return  parameter
                type  
    
    So, calling sum(1,3) would require function<int(int, int) as you are passing two parameters and returning a value.
    */
    

    More examples

    /*
    The structure is "return_type(param1, param2, ..)" for the function and the following 
    `[]` is used for variable capture (by value [x] or by reference [&x]) that resides out the function.
    */
    
    // takes one param and returns nothing
    function<void(int)> print = [](auto i) {
       court<<i<<endl;
    }
    
    // takes two params and returns the sum
    function<int(int, int)> sum = [](auto i, auto j) {
       return i + j;
    }
    
    // takes one param and returns with added 2
    function<int(int)> sum = [](auto i) {
       return i + 2;
    }
    

    How do we define classes that take the template types like "int(int, int)"?

    template<typename T>
    class Class {
      public:
        void call(T sum) {
          cout << sum(1, 3) << endl;
        } 
    };
    
    // usage
    auto sum = [](auto a, auto b) { return a + b; };
    auto instance = new Class<decltype(sum)>();
    instance->call(sum);