目录
  • 1函数对象Functor(仿函数)
    • 1.1概念
    • 1.2代码实例
    • 1.3调用效率
  • 2.匿名函数对象Lambda表达式
    • 2.1使用形式
    • 2.2代码实例
  • 3总结

    1函数对象Functor(仿函数)

    1.1概念

    函数对象就是类对象,生成这个类对象的类中,拥有一个小括号运算符重载函数。

    重载了小括号运算符的类的类对象,就叫函数对象。

    1.2代码实例

    #include <iostream>
    using namespace std;
    template <class T1>
    class A
    {
        T1 name;
    public:
        A(T1 name)
        {
            this->name=name;
        }
        void operator()()
        {
            cout<<this->name<<endl;
        }
    };
    int main()
    {
        A<string> a("da jia hao");
        a();
        return 0;
    }

    1.3调用效率

    函数对象相较于普通函数与函数指针的调用效率要高很多

    当我们用普通函数的时候:像下面这种情况,每次都需要回调,特别的繁琐。

    注意:在这个代码里面,即使我们在函数前面都加上inline变成内联函数,也是不行的,因为我们使用的是函数指针,即使变成了内联函数,我们还是需要回调。

    #include <iostream>
    using namespace std;
    template <class T>
    T my_bigger(T a,T b)
    {
        return a>b?a:b;
    }
    template <class T>
    T my_less(T a,T b)
    {
        return a>b?b:a;
    }
    template <class T,class Compare>
    T my_compare(T a, T b,Compare f)
    {
        return f(a,b);
    }
    int main()
    {
        cout<< my_compare<int>(10,20,my_less<int>)<<endl;
        cout<<my_compare<int>(10,20,my_bigger<int>)<<endl;
        return 0;
    }

    使用函数对象就可以解决这个问题,因为使用函数对象就相当于在函数面前加上一个inline,效率会提升,代码如下:

    #include <iostream>
    using namespace std;
    template <class T,class Compare>
    T my_compare(T a, T b,Compare f)
    {
        return f(a,b);
    }
    template <class T>
    class A
    {
    public:
        T operator()(T a,T b)
        {
            return a>b?a:b;
        }
    };
    template <class T>
    class B
    {
    public:
        T operator()(T a,T b)
        {
            return a>b?b:a;
        }
    };
    int main()
    {
        cout<<my_compare(10,20,A<int>())<<endl;
        cout<<my_compare(10,20,B<int>())<<endl;
        return 0;
    }

    2.匿名函数对象Lambda表达式

    2.1使用形式

    auto + 名字 =[]()->返回值{};

    具体介绍:

    1.[] 中括号表示函数对象的构造函数中是否接收外部变量。 [&] ,表示使用引用的方式获取外部变量 [=],表示使用值的拷贝的方式获取外部变量。

    2.() 这个小括号是就函数对象中的小括号符后面的参数列表。

    3.->返回值,需要就放,不需要就不放。根据自己需要,任君选择。

    4.{…} 就是函数对象的小括号运算符的函数体。

    2.2代码实例

    第一个当[]里面没用东西时:

    #include <iostream>
    using namespace std;
    class A
    {
    public:
        A()
        {
        }
        void operator()()
        {
        }
    };
    int main()
    {
        auto f=[]()->void{cout<<"我是大哥"<<endl;};
        f();
        return 0;
    }

    第二个当[]里面有东西时:(实现交换)

    #include <iostream>
    using namespace std;
    class A
    {
        int a;
    public:
        A(int &a)
        {
            this->a=a;
        }
        void operator()()
        {
        }
    };
    int main()
    {
        int a=10;
        int b=20;
        auto f=[&]()->void
        {
            int temp=a;
            a=b;
            b=temp;
        };
        f();
        cout<<a<<endl;
        cout<<b<<endl;
        return 0;
    }

    注意点:

    当时候=号的时候,底层实现用的是const,这样就不能进行赋值等一系列操作,如下代码,我们可以加上一个mutable,C++11所提供的新的关键字mutale,是一种易变是的修饰符。当然下面这个代码肯定不能实现交换,我只是用来做一个说明。

    #include <iostream>
    using namespace std;
    class A
    {
        int a;
    public:
        A(int &a)
        {
            this->a=a;
        }
        void operator()()
        {
        }
    };
    int main()
    {
        int a=10;
        int b=20;
        auto f=[=]()mutable
        {
            int temp=a;
            a=b;
            b=temp;
        };
        f();
        return 0;
    }

    3总结

    在C++中Funtor也被称为函数符:

    函数符就有四种表现形式:

    1.全局函数指针

    2.成员函数指针

    3.函数对象

    4.Lambda匿名函数对象(Lambda表达式)

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。