zoukankan      html  css  js  c++  java
  • 函数对象与仿函数(function object and functor)

    part 1. 仿函数在STL组件中的关系

      如下图:

      # 仿函数配合算法完成不同的策略变化。

      # 适配器套接仿函数。

    part 2. 仿函数介绍

      传递给算法的“函数型实参”不一定得是函数,可以是行为类似函数的对象。这种对象称为函数对象(function object),或称为仿函数(functor)。——《STL标准库(第2版)》 P233

      1. 函数对象 = 仿函数。并且,function object = functor

      2. 函数对象(仿函数)有四种实现方式:函数指针(fucntion pointer)、lambda表达式、“带有成员函数 operator()”的class建立的object、“带有转换函数可以将自己转换为 pointer to function”的class所建立的object。

      2.1 仿函数的实现原理:向算法传递的,终究是个函数。以上四种方式被调用时,终究是个函数。

      3. 下面的所有例子,均为 vector 容器排序,但是采用不同的函数对象实现方式。

      3.1 函数指针(function pointer)

      使用函数指针作为“传递给算法的‘函数型实参’”。

    bool compareLength(const string& lhs, const string& rhs)
    {
        return lhs.size() > rhs.size();
    }
    
    int main()
    {
        vector<string> v = { "I", "love", "you" };
        sort(v.begin(), v.end(), compareLength);
        for(auto &s : v)
            cout << s << " ";
        return 0;
    }
    // 输出结果:
    // love you I

      3.2 lambda表达式

      lambda 是一种隐式的预定义函数对象。

      使用 lambda表达式 作为“传递给算法的‘函数型实参’”。

    int main()
    {
        vector<string> v = { "I", "love", "you" };
    
        sort(v.begin(), v.end(), 
            [](const string& lhs, const string& rhs) 
                { return lhs.size() > rhs.size(); });
    
        for(auto &s : v)
            cout << s << " ";
        return 0;
    }
    // 输出结果:
    // love you I

       

      3.3 “带有成员函数 operator()”的class/struct建立的object

      根据个人经验,如果不考虑类内访问权限,在这里使用 struct 是写更少代码的写法。因为 class 默认的访问权限是 private ,所以还要多谢一行 public:。也就是说,用 class 你要这样写:

    class CompareSize
    {
    public:
        bool operator() (const string& lhs, const string& rhs)
        {
            return lhs.size() > rhs.size();
        }
    };

      如果用 struct 你要这样写:

    struct CompareSize
    {
        bool operator() (const string& lhs, const string& rhs)
        {
            return lhs.size() > rhs.size();
        }
    };

      使用“带有成员函数 operator()”的class/struct建立的object 作为 “传递给算法的‘函数型实参’” 的完整代码如下:

    struct CompareSize
    {
        bool operator() (const string& lhs, const string& rhs)
        {
            return lhs.size() > rhs.size();
        }
    };
    
    int main()
    {
        vector<string> v = { "I", "love", "you" };
        sort(v.begin(), v.end(), CompareSize());
        for(auto &s : v)
            cout << s << " ";
        return 0;
    }
    // 输出结果:
    // love you I

      3.3.1 用 struct 还是 class ?

      使用 class 和 struct 定义类唯一的区别就是默认的访问权限——《C++ primer (5th)》 P241

      所谓默认访问权限:定义在第一个访问说明符之前的成员,使用默认的访问权限。访问说明符有 public、protected、private。

      3.3.2 用 lambda表达式 还是 functor?

      首先,functor 泛指“带有成员函数 operator()”的 class/struct 建立的 object。其次,在语义明确,代码结构短小变量生存周期清晰,不追求复用的前提下,使用 lambda;否则使用 functor

      

      3.4“带有转换函数可以将自己转换为 pointer to function”的class所建立的object

      (下次再写)

    part 3. 仿函数适配器

      (下次再写)

  • 相关阅读:
    Spring Boot 应用监控
    学习学习SpringSecurity
    Spring Cloud 简介
    thinkphp 请求
    八、主从复制
    七、AOF 持久化
    五、五大数据类型实现原理
    六、RDB 持久化
    四、redis的底层数据结构
    三、五大数据类型详细用法
  • 原文地址:https://www.cnblogs.com/fengyubo/p/4781645.html
Copyright © 2011-2022 走看看