Functors! Not functions

This is the topic that sounds scary on listening but once you understand the internal meaning, its as easy as an ice cake.

In simple words, its a fancy way of saying 'overloading () operator' as Functors or simply 'using objects as functions' . If you don't know what operator overloading is, don't worry we will go through it. If you already know what operator overloading is, skip to Functors .

Operator Overloading in C++

Just like you add two numbers you can add 2 objects using this concept. It is simply overloading a operator to work with our user defined objects rather than just predefined objects.

int a=5,b=3,c=a+b;
myObject objA(10);
myObject objB(20);
myObject objC=objA+objB;

Here as you add 2 integers to c, you are adding 2 object values and storing it in ObjC. If you directly compile the above code, that will give you an error, as we cannot add two objects directly. This is where we use + operator overloading concept to achieve such a operation. This is done by writing an operator function as the below syntax

return_type operator op(parameters){
    statements;
    ....
}

op can be any operator you wish to overload. Example + ,-,* etc., there are few exceptions for operators that can be overloaded.

These are few operators which you cannot overload. . Member access or dot operator,? : Ternary or conditional operator,:: Scope resolution operator,.* Pointer to member operator,sizeof The object size operator,typeid Object type operator.

Below is the class definition for implementing + operator overloading along with some additional code.

class myObject{
    private:
        int _value;
    public:
        myObject(){}
        myObject(int a){
            _value=a;
        }
// +(plus) operator overloading
    myObject operator +(myObject obj){
        myObject temp;
        temp._value=_value+obj._value;
        return temp;
    }

// function to print present value
    void print(){
        cout<<"value: "<<_value<<endl;
    }
};
int main(){
    myObject objA(10);
    myObject objB(20);
    myObject objC=objA+objB; //3rd line in main function
    objC.print(); //prints : value: 30
}

In the third line of main function, what myObject class does is, first it detects objA is trying to overload + operator, then once after detecting it sends objB as a parameter to objA's operator overloading function. Here in the function it creates a temporary temp object of same class and assigns value by adding values of both current object value_value and value in objB by obj._value.It then returns this temp object, this returned object is assigned to objC. This is how objC gets its value.

On printing the value of objC by using objC.print() function we get output as value: 30 which indicates _value variable in objC is being assgined.

This is how operator overloading is performed in c++ and this is how you can add value(or meaning) to specific operator when used with user defined objects.

Now lets go exploring what functors are,

Functors

Functors concept is nothting but making objects act like functions.

myObject obj(10);
cout<<obj(2); //this will output 20, here you are trying to multiply obj value by 2

In the second line, the object obj is acting like function, this is achieved by the concept Functors. Here this function mutiplies the value of object obj 10 by given parameter value 2 and returns the multiplied value 20.

This is achieved by overloading () operator. Below is the class definition that implements this operator overloading.

class myObject{
    private:
        int _value;
    public:
        myObject(){}
        myObject(int a){
            _value=a;
        }
    int operator ()(int value){
        return _value*value;
    }
};

As in above class definition, everytime an object is called as a function, it returns the value of object _value multiplied by passed parameter. Complete code of above implementation :

#include <iostream>
using namespace std;

class myObject{
    private:
        int _value;
    public:
        myObject(){}
        myObject(int a){
            _value=a;
        }
    int operator ()(int value){
        return _value*value;
    }
};
int main(){
    myObject obj(10);
    cout<<obj(4); //prints : 40
}

Use case for functors than just using functions could be, for suppose you are declaring an object with a value, so this value is preserved inside that object acting as a state, and every time you execute a functor(i.e, every time you call object as a function) you make changes to the existing state and you are not just excuting a function( as functions don't maintain a state ).

So in the above code you are multiplying the number 4 to the value 10. Here the value 10 is not hardcoded, its the state maintained by object obj.I could create another object with another state value and I can apply any changes to the value. Here I am applying changes to the state of an object not an hardcoded value, this is where functors are useful.

CONCLUSION :

FUNCTORS ARE THE OBJECTS WHICH COULD BE USED LIKE A FUNCTION

Thank you for spending your time reading my content. It means a lot to me.I like reading and listening to your comments. Your feedback motivates me to write more and more posts, please take a moment to leave your feedback ❤.
Thank You

17