Home C++ Introduction Decisions Loops Input/Output Functions Stack and Heap References Arrays Searching and Sorting Recursion Pointers Character and Strings Structures Classes Inheritance Exceptions Templatess STL Modern C++ Misc Books ----

Lambdas


Contents

std::function

We have a class template called "std::function" that can store
either a function, a functor or a lambda expression. It is used as
a callable object that stores the functionality and can be used
later to call the embedded function.

The "std::function" is not a type but a class template that takes a
function signature like:

R(Args...)

Now this is also not a type in the sense we cannot create an object
from it using the notation:

R(Args...) object ;

It is more of a language feature that is very specialized and
( no pun intended ) is used in:
1) Template Specialization
2) std::function

The "R(Args...)" is like a function signature with "R" sepcifying the
return type and Args representing a variable number of arguments.


File: template1.cpp
#include <iostream>
#include <string>
#include <utility> // For forward
#include <functional>

using namespace std ;

// Primary template definition
template <typename T>
class FunctionHandler
{
    public:
    void handle(T val)
    {
        cout << "Handling generic type: " << typeid(T).name() << endl;
    }
};

// Partial specialization for function types R(Args...)
template <typename R, typename... Args>
class FunctionHandler<R(Args...)>
{
    public:
    void handle(R (*func)(Args...)) {
        cout << "Handling function pointer with return type " << typeid(R).name()
                  << " and arguments: ";
        // A more advanced implementation could iterate through Args... to print types
        cout << " (function pointer)" << endl;
        //callable_ptr(args...)
    }

    void handle(function<R(Args...)> func) {
        cout << "Handling function with return type " << typeid(R).name()
                  << " and arguments: ";
        cout << " (function)" << endl;
    }
};

// A sample function for demonstration
int add(int a, int b) {
    return a + b;
}

void greet(const string& name) {
    cout << "Hello, " << name << "!" << endl;
}

int main() {
    // Generic type handling
    FunctionHandler<int> intHandler;
    intHandler.handle(10);

    FunctionHandler<string> stringHandler;
    stringHandler.handle("test");

    // Function pointer handling
    FunctionHandler<int(int, int)> addHandler;
    addHandler.handle(&add);

    //function handling
    function<void(const string&)> greetFunc = greet ;
    FunctionHandler<void(const string&)> greetHandler;
    greetHandler.handle(greetFunc);

    return 0;
}

$ g++ template1.cpp ; ./a.exe
Handling generic type: i
Handling generic type: Ss
Handling function pointer with return type i and arguments:  (function pointer)
Handling function with return type v and arguments:  (function)

From the above code we have:

	// Primary class template (declaration only, intended for function types)
	template 
	class CallableWrapper;

	// Specialization for function type R(Args...)
	template 
	class CallableWrapper {

We cannot use "R(Args...)" in a template declaration by itself. It has to
be in a template specialization. What the above declaration is saying is that;
we can pass a function type such as a lambda, a function or a function pointer to the
"CallableWrapper" . However we cannot pass a functor object or a
std::function object.
The other use case is for the "std:function".
File: function1.cpp
#include <iostream>
#include <functional>

int add(int a, int b)
{
    return a + b;
}

class Multiply
{
   public:
    int operator()(int a, int b) {
        return a * b;
    }
};

int main()
{
    // Store a regular function
    function<int(int, int)> f1 = add;
    cout << "Result of add(5, 3): " << f1(5, 3) << endl;


    // Store a lambda expression
    function<int(int, int)> f2 = [](int a, int b) { return a - b; };
    cout << "Result of lambda (-5, 3): " << f2(-5, 3) << endl;

    // Store a function object
    Multiply multiplier;
    function<int(int, int)> f3 = multiplier;
    cout << "Result of Multiply(7, 4): " << f3(7, 4) << endl;

    //Store a function pointer
    int(*func_ptr)(int, int) = add;
    function<int(int, int)> f4 = func_ptr;
    cout << "Result of func_ptr(10, 2): " << f4(10, 2) << endl;

    return 0;
}

$ g++ function1.cpp ; ./a.exe
Result of add(5, 3): 8
Result of lambda (-5, 3): -8
Result of Multiply(7, 4): 28
Result of func_ptr(10, 2): 12


The above file shows how we can use "std::function" template.
std::function



Exercise



File: function_ex1.cpp
#include <iostream>
#include <functional>

using namespace std ;

void printString(const string& str1)
{
    cout << str1 << endl ;
}


int main()
{
    //Create a std::function object called f1. Store the function
    //printString in it.

    //TO DO
    const string str1 =  "Hooray. Almost end of Semester."  ;
    cout << "Result of f1: " ;
    f1( str1 ) ;

    //Create a std::function object called f2. Store
    //a lambda expression that does the same thing
    //as printString. The capture clause is empty and
    //it takes a single argument of type "const string&"
    //printString in it.

    //TO DO
   cout << "Result of f2: " ;
   f2( str1 ) ;




    return 0;
}
















































Solutions



File: function_ex1s.cpp