STL学习笔记(4)- STL算法导论for_each和仿函数

原创
2022-11-24
4384
0

STL提供了 for_each 函数,对容器某个范围内的提供统一的函数调用的函数。
下面是一个 for_each 的基本用法示例,将数组 vector 中的每一个元素内容* 2
使用 for_each 时,需要使用头文件 <algorithm>
具体代码如下:

#include <iostream>
#include <algorithm>
#include <vector>

template<typename T>
class Func
{
public:
    void operator() (T& d)
    {
        d *= 2;
    }
};

int main(int argc, char** argv)
{
    std::vector<int> vector;
    vector.push_back(20);
    vector.push_back(30);
    vector.push_back(10);
    vector.push_back(40);

    std::for_each(vector.begin(), vector.end(), Func<int>());

    for (auto value : vector)
        std::cout << value << std::endl;

    system("pause");
    return 0;
}

程序的运行结果如下:
40
60
20
80

其中 Func 就是一个仿函数,我们把重载了运算符 () 的类叫做仿函数。当然我们也可以使用lambda表达式,实际上lambda表达式就是一个匿名的仿函数。

对于for_each的实现,基本代码如下:

template<class _InIt,
    class _Fn1> inline
    void _For_each_unchecked(_InIt _First, _InIt _Last, _Fn1& _Func)
    {	// perform function for each element
    for (; _First != _Last; ++_First)
        _Func(*_First);
    }

template<class _InIt,
    class _Fn1> inline
    _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
    {	// perform function for each element
    _DEBUG_RANGE_PTR(_First, _Last, _Func);
    _For_each_unchecked(_Unchecked(_First), _Unchecked(_Last), _Func);
    return (_Func);
    }

上面的代码并不难,最关键的代码为下面这句

for (; _First != _Last; ++_First)
        _Func(*_First);
    }

可以看出, for_each 函数对给入范围内的值都做了一遍我们输入的函数操作。

  • _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
  • _First 和 _Last 为给定的范围
  • _Func 输入的回掉函数,一般为仿函数
  • 返回值为,处理后的输入反函数对象

为什么要使用仿函数呢?我们在当我们处理数据的时候想要完成其他的操作,这个时普通的回掉函数无法完成的,比如上面的例子除了对数组中的元素都 * 2 之外还要对计算出最大值、最小值、和等信息。我们就可以将代码改写为如下:

#include <iostream>
#include <algorithm>
#include <vector>

template<typename T>
class Func
{
public:
    void operator() (T& d)
    {
        d *= 2;

        if (m_Count == 0)
        {
            m_MaxValue = d;
            m_MinValue = d;
            m_Sum = d;
        }
        else
        {
            m_MaxValue = m_MaxValue > d ? m_MaxValue : d;
            m_MinValue = m_MinValue > d ? d : m_MinValue;
            m_Sum += d;
        }

        m_Count++;
    }

    T getMaxValue() {
        return m_MaxValue;
    }

    T getMinValue() {
        return m_MinValue;
    }

    T getSum() {
        return m_Sum;
    }

private:
    int m_Count = 0;
    T m_MaxValue;
    T m_MinValue;
    T m_Sum;
};

int main(int argc, char** argv)
{
    std::vector<int> vector;
    vector.push_back(20);
    vector.push_back(30);
    vector.push_back(10);
    vector.push_back(40);

    Func<int> &pFunc = std::for_each(vector.begin(), vector.end(), Func<int>());

    for (auto value : vector)
        std::cout << value << std::endl;

    std::cout << "------------------------------------------" << std::endl;
    std::cout << pFunc.getMinValue() << " " << pFunc.getMaxValue() << " " << pFunc.getSum() << std::endl;

    system("pause");
    return 0;
}

运行结果为:
40
60
20
80
------------------------------------------
20 80 200

不会飞的纸飞机
扫一扫二维码,了解我的更多动态。

下一篇文章:STL学习笔记(5)- STL的函数适配器bind1st和bind2nd