理解c++的迭代器 (c++迭代器的方法有哪些)

定义一个对容器全部元素执行某种算术运算的算法,使用的某种算术运算使用函数指针或函数对象来定义,全部元素的遍历使用迭代器。实质就是对STL算法accumulate的模拟实现,该算法定义在头文件<numeric>中。

使用函数指针或函数对象做函数参数,调用时,相当于将函数指针指向的代码或类定义的operator()()定义的代码嵌入到函数中,让函数体中的一段代码可以让任意的代码逻辑来替换,从而让函数更灵活,更通用,也更稳定。(使用函数指针的函数如果称为主体函数,主体函数通过函数指针或函数对象调用的函数称为回调函数,某一函数调用主体函数时,可以随意定义回调函数,从而构成了一对多(一个主体函数,任意多个回调函数)的关系。)

template <class InputIterator, class T, 
          class BinaryOperation>            // BinaryOperation提供运算逻辑
T accumulate (  InputIterator   first, 
                InputIterator   last, 
                T               init,
                BinaryOperation binary_op) // 使用函数指针或函数对象
{
    while(first!=last) {
        init=binary_op(init,*first);//调用函数指针,binary_op的参数是accumulate提供的参数
        ++first;
    }
    return init;
}

在上面函数accumulate的形参列表中,使用了函数指针或函数对象参数,函数指针或函数对象在函数体中使用时,使用的参数也是函数accumulate的参数。

accumulate调用时,如果使用的是函数指针,直接引用函数名即可:

int mult(int a,int b)
{
    return a*b;
}
// ……
accumulate(A, A + N, 1, mult);        //将函数mult 传递给通用算法

accumulate调用时,如果使用的是函数对象,其实参是一个类对象:

class multclass{
public:
    int operator() (int x, int y) const { return x*y;}
}; 
// ……
accumulate(A, A + N, 1, multclass()); //调用默认构造函数生成一个匿名对象
// 匿名对象在accumulate函数体中调用operate()()

完整demo code:

#include <iostream>
//#include <numeric> // 定义accumulate()的头文件
using namespace std;

template <class InputIterator, class T>
T accumulate (InputIterator first, 
              InputIterator last,   // 由first与last提供操作区间
              T init)               // init提供初始值
{                             
    while (first!=last) {     // 遍历first和last构成的区间
        init = init + *first; // 不使用函数指针,如果要使用乘操作,需要更改运算符
        ++first;              // 迭代器前移
    }
    return init;
}

template <class InputIterator, class T, 
          class BinaryOperation>            // BinaryOperation提供运算逻辑
T accumulate (  InputIterator   first, 
                InputIterator   last, 
                T               init,
                BinaryOperation binary_op) // 使用函数指针或函数对象
{
    while(first!=last) {
        init=binary_op(init,*first);//调用函数指针,binary_op的参数是accumulate提供的参数
        // 如果使用函数对象,bionary_op就是一个匿名对象,由其调用operator()(init,*first)
        ++first;
    }
    return init;
}

int mult(int a,int b)
{
    return a*b;
}

class multclass{
public:
    int operator() (int x, int y) const { return x*y;}
}; 
 
void main()
{
    int A[] = {1,2,3,4,5};
    const int N = sizeof A / sizeof *A;
    cout << "The result by adding all elements in A is "
         << accumulate(A, A + N, 0)             //使用默认运算逻辑
         << "(使用默认运算逻辑(加法)" << endl;
    cout << "The result by multipling all elements in A is "
         << accumulate(A, A + N, 1, multclass()) //调用默认构造函数生成一个匿名对象
         << "(使用函数对象传递运算逻辑)" << endl;
    cout << "The result by mult all elements in A is "
         << accumulate(A, A + N, 1, mult)        //将函数mult 传递给通用算法
         << "(使用函数指针传递运算逻辑)" << endl;
    getchar();
}
/*
The result by adding all elements in A is 15(使用默认运算逻辑(加法)
The result by multipling all elements in A is 120(使用函数对象传递运算逻辑)
The result by mult all elements in A is 120(使用函数指针传递运算逻辑)
*/

-End-