C++STL standard library learning note function object

catalogue

preface:

Text:

1. Function object

2. Function object class template in STL

3. Application of greater

4. Use custom large and small relationships in STL

5. Example: write MyMax template

Postscript:

preface:

In this note, I annotated most of the code. Some of my ideas and comments were marked in blue, and the key points and areas needing attention were marked in red.

In this article, we mainly introduce the function objects in STL.

Text:

1. Function object

If a class overloads the operator "()", the object of that class becomes a function object

Example 1:

#include<iostream>
using namespace std;

class CMyAverage
{//Function object class
    public:
    double operator()(int a1,int a2,int a3)
    {
        return (double)(a1+a2+a3)/3;
    }
};

int main(int argc, char const *argv[])
{
    CMyAverage average;//Function object
    cout<<average(3,2,3);//Equivalent to average operator()(3,2,3)
    //Output: 2.66667
    return 0;
}

Example 2:

#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<functional>
using namespace std;

int sumSquares(int total, int value)
{
    return total + value*value;
}

template<class T>
void PrintInterval(T first, T last)
{//Elements in the output interval [first, last]
    for (; first != last; ++first)
    {
        cout<<*first<<" ";
    }
    cout<<endl;
}

template<class T>
class SumPowers
{
    private:
    int power;
    public:
    SumPowers(int p):power(p){}
    const T operator()(const T & total, const T & value)
    {//Calculate the power of value and add it to total
        T v = value;
        for (int i = 0; i < power-1; i++)
        {
            v = v * value;
        }
        return total + v;
    }
};

int main(int argc, char const *argv[])
{
    const int SIZE = 10;
    int a1[] = {1,2,3,4,5,6,7,8,9,10};
    vector<int> v(a1,a1+SIZE);
    cout<<"1)";
    PrintInterval(v.begin(),v.end());
    int result = accumulate(v.begin(),v.end(),0,sumSquares);
    //Find the sum of the squares of all the elements above v
    cout<<"2)Sum of squares"<<result<<endl;
    result = accumulate(v.begin(),v.end(),0,SumPowers<int>(3));
    //In sumpowers < int > (3), this is an object where power = 3
    //Find the cubic sum of all the elements above v
    cout<<"3)Cubic sum"<<result<<endl;
    result = accumulate(v.begin(),v.end(),0,SumPowers<int>(4));
    cout<<"4)4 Power sum"<<result<<endl;
    return 0;
}
/*
Output:
1)1 2 3 4 5 6 7 8 9 10 
2)Sum of squares 385
3)Cubic and 3025
4)4 Power and 25333
*/

Of which:

In int result = calculate (v.begin(), v.end(), 0, sumsquares)

In this code, we instantiate:

int accumlate(vector<int>::iterator first, vector<int>::iterator last, int init, int(*op)(int,int))
{
    for (; first != last; ++first)
    {
        init = op(init,*first);
    }
    return init;
}

While in accumulate (v.begin(), v.end(), 0, sumpowers < int > (3));

The example shows that:

int accumlate(vector<int>::iterator first, vector<int>::iterator last, int init, SumPowers<int>op)
{
    for (; first != last; ++first)
    {
        init = op(init,*first);
    }
    return init;
}

Value of function object:

In the example just now, suppose we ask for an array of 1, 2, 3, 4, 5, 6, 7, 8, 9 Power sum. If you don't use a function object, you may have to write n more functions (although the teacher said so, can I pass in a parameter to know how many powers to do? However, from this example, it seems that the function supported by accumulate only supports the passing in of two parameters, an init and a value. In this case, you still have to use a function object)

2. Function object class template in STL

The following templates can be used to generate function objects.

        equal_to

        greater

        less

        ......

They are all templates and also implement the member function "()"

They are defined in the header file: < functional >

For example:

template<class T>
struct greater:public binary function<T,T,bool>
{
    bool operator()(const T&x,const T&y)const
    {
        return x > y;
    }
};

3. Application of greater

list has two sort member functions

        void sort();

Arrange the elements in the list in ascending order according to the comparison method specified by "<".

        template<class Compare>

        void sort(Compare op)

Sort the elements in the list in ascending order according to the comparison method specified by Op. That is, to compare the size of X and y, look at the return value of op(x,y). If it is true, it is considered that x is less than y

Example:

#include<list>
#include<iostream>
using namespace std;

class myless
{

public:
    bool operator()(const int & c1, const int & c2)
    {
        return (c1 % 10)<(c2 % 10);//Compare single digit size
    }
};
template<class T>
void Print(T first, T last)
{
    for (; first != last; ++first)
    {
        cout<<*first<<",";
    }
    
}

int main(int argc, char const *argv[])
{
    const int SIZE = 5;
    int a[SIZE] = {5,21,14,2,3};
    list<int> lst(a,a+SIZE);
    lst.sort(myless());
    Print(lst.begin(),lst.end());
    cout<<endl;//Output: 21,2,3,14,5,
    lst.sort(greater<int>());//Greater < int > () is an object
    Print(lst.begin(),lst.end());
    cout<<endl;//Output: 21,14,5,3,2,
    return 0;
}

There is nothing to emphasize.

4. Use custom large and small relationships in STL

Many algorithms in the association container and STL can customize the comparator with functions or function objects. When the comparator op is customized, the following three statements are equivalent:

1) x is less than y

2) op(x,y) returns true

3) y is greater than x

5. Example: write MyMax template

#include<iostream>
#include<iterator>
using namespace std;

class MyLess
{
public:
    bool operator()(int a1, int a2)
    {
        if((a1%10)<(a2%10))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
};

bool Mycompare(int a1, int a2)
{
    if((a1%10)<(a2%10))
    {
        return false;
    }
    else
    {
        return true;
    }
    
}

template<class T, class Pred>
T MyMax(T first, T last, Pred myless)
{
    T tmpMax = first;
    for (; first != last; ++first)
    {
        if (myless(*tmpMax, *first))
        {
            tmpMax = first;
        }
        
    }
    return tmpMax;
}

int main(int argc, char const *argv[])
{
    int a[] = {35,7,13,19,12};
    cout<<*MyMax(a,a+5,MyLess())<<endl;//Output: 19
    cout<<*MyMax(a,a+5,Mycompare)<<endl;//Output: 12
    return 0;
}

Postscript:

In this section, I feel that the content is much more abstract, but the support of c + + for these things (referring to the set of functions in the function) is still very surprising.

Keywords: C++ STL

Added by Revan on Tue, 25 Jan 2022 06:45:53 +0200