zoukankan      html  css  js  c++  java
  • 【C++标准库】STL函数对象及Lambda

    函数对象function object,又称仿函数functors,是定义了operator()的对象。

    class FunctionObjectType
    {
        public:
            void operator() ()
                {
                    //statement
                }
    }

     1 /* The following code example is taken from the book
     2 * "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
     3 * by Nicolai M. Josuttis, Addison-Wesley, 2012
     4 *
     5 * (C) Copyright Nicolai M. Josuttis 2012.
     6 * Permission to copy, use, modify, sell and distribute this software
     7 * is granted provided this copyright notice appears in all copies.
     8 * This software is provided "as is" without express or implied
     9 * warranty, and with no claim as to its suitability for any purpose.
    10 */
    11 #include <iostream>
    12 #include <string>
    13 #include <deque>
    14 #include <set>
    15 #include <algorithm>
    16 using namespace std;
    17 
    18 
    19 /* class Person
    20 */
    21 class Person {
    22 private:
    23     string fn;    // first name
    24     string ln;    // last name
    25 public:
    26     Person() {
    27     }
    28     Person(const string& f, const string& n)
    29         : fn(f), ln(n) {
    30     }
    31     string firstname() const;
    32     string lastname() const;
    33     // ...
    34 };
    35 
    36 inline string Person::firstname() const {
    37     return fn;
    38 }
    39 
    40 inline string Person::lastname() const {
    41     return ln;
    42 }
    43 
    44 ostream& operator<< (ostream& s, const Person& p)
    45 {
    46     s << "[" << p.firstname() << " " << p.lastname() << "]";
    47     return s;
    48 }
    49 
    50 
    51 /* class for function predicate
    52 * - operator () returns whether a person is less than another person
    53 */
    54 class PersonSortCriterion {
    55 public:
    56     bool operator() (const Person& p1, const Person& p2) const {
    57         /* a person is less than another person
    58         * - if the last name is less
    59         * - if the last name is equal and the first name is less
    60         */
    61         return p1.lastname()<p2.lastname() ||
    62             (p1.lastname() == p2.lastname() &&
    63                 p1.firstname()<p2.firstname());
    64     }
    65 };
    66 
    67 
    68 int main()
    69 {
    70     Person p1("nicolai", "josuttis");
    71     Person p2("ulli", "josuttis");
    72     Person p3("anica", "josuttis");
    73     Person p4("lucas", "josuttis");
    74     Person p5("lucas", "otto");
    75     Person p6("lucas", "arm");
    76     Person p7("anica", "holle");
    77 
    78     // declare set type with special sorting criterion
    79     typedef set<Person, PersonSortCriterion> PersonSet;
    80 
    81     // create such a collection
    82     PersonSet coll;
    83     coll.insert(p1);
    84     coll.insert(p2);
    85     coll.insert(p3);
    86     coll.insert(p4);
    87     coll.insert(p5);
    88     coll.insert(p6);
    89     coll.insert(p7);
    90 
    91     // do something with the elements
    92     // - in this case: output them
    93     cout << "set:" << endl;
    94     PersonSet::iterator pos;
    95     for (pos = coll.begin(); pos != coll.end(); ++pos) {
    96         cout << *pos << endl;
    97     }
    98 }
    View Code

    for_each获取function object的状态

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    class MeanValue
    {
    private:
        long num; //num of elements
        long sum; //sum of values
    public:
        MeanValue():num(0),sum(0)
        {
        }
        void operator() (int elem)
        {
            ++num;
            sum += elem;
        }
        double value()
        {
            return static_cast<double>(sum) / static_cast<double>(num);
        }
    };
    
    int main()
    {
        vector<int> coll = { 1,2,3,4,5,6,7,8 };
        MeanValue mv = for_each(coll.begin(), coll.end(), MeanValue());
        cout << "mean value:" << mv.value() << endl;
        return 0;
    }
    View Code

     预定义的function object

    C++标准库提供了许多预定义的function object和binder,后者允许你合成更多精巧的function object。使用时需包含头文件<functional>

    bind()函数对象适配器

     1 #include <iostream>
     2 #include <functional>
     3 using namespace std;
     4 using namespace std::placeholders; //定义占位符
     5 
     6 int main()
     7 {
     8     auto plus10 = bind(plus<int>(), _1, 10); //以占位符_1表示第一个参数,以10为第二个参数
     9     cout << "+10: " << plus10(7) << endl;   //17
    10 
    11     auto plus10times2 = bind(multiplies<int>(),
    12                             bind(plus<int>(),
    13                                 _1, 10),
    14                                 2);
    15     cout << "+10*2: " << plus10times2(7) << endl; //34
    16 
    17     auto pow3 = bind(multiplies<int>(),bind(multiplies<int>(),_1, _1),_1);
    18     cout << "x*x*x: " << pow3(7) << endl;
    19 
    20     auto inversDivide = bind(divides<double>(), _2, _1);
    21     cout << "invdiv: " << inversDivide(49, 7) << endl;  // 1/7
    22     return 0;
    23 }
    View Code

     运用Lambda

    Lambda提供了一种直观、易读的方式,可将独特的行为传递给算法和容器的成员函数。

    Lambda表达式完整声明格式如下:

    [capture list] (params list) mutable exception-> return type { function body }

    其中:

    1. capture list:捕获外部变量列表
    2. params list:形参列表
    3. mutable指示符:用来说用是否可以修改捕获的变量
    4. exception:异常设定
    5. return type:返回类型
    6. function body:函数体

    Lambda调用全局函数

     1 /* The following code example is taken from the book
     2 * "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
     3 * by Nicolai M. Josuttis, Addison-Wesley, 2012
     4 *
     5 * (C) Copyright Nicolai M. Josuttis 2012.
     6 * Permission to copy, use, modify, sell and distribute this software
     7 * is granted provided this copyright notice appears in all copies.
     8 * This software is provided "as is" without express or implied
     9 * warranty, and with no claim as to its suitability for any purpose.
    10 */
    11 #include <iostream>
    12 #include <algorithm>
    13 #include <locale>
    14 #include <string>
    15 using namespace std;
    16 
    17 char myToupper(char c)
    18 {
    19     std::locale loc;
    20     return std::use_facet<std::ctype<char> >(loc).toupper(c);
    21 }
    22 
    23 int main()
    24 {
    25     string s("Internationalization");
    26     string sub("Nation");
    27 
    28     // search substring case insensitive
    29     string::iterator pos;
    30     pos = search(s.begin(), s.end(),           // string to search in
    31         sub.begin(), sub.end(),       // substring to search
    32         [](char c1, char c2) {      // compar. criterion
    33         return myToupper(c1) == myToupper(c2);
    34     });
    35     if (pos != s.end()) {
    36         cout << """ << sub << "" is part of "" << s << """
    37             << endl;
    38     }
    39 }
    View Code

    Lambda调用成员函数

     1 /* The following code example is taken from the book
     2 * "The C++ Standard Library - A Tutorial and Reference, 2nd Edition"
     3 * by Nicolai M. Josuttis, Addison-Wesley, 2012
     4 *
     5 * (C) Copyright Nicolai M. Josuttis 2012.
     6 * Permission to copy, use, modify, sell and distribute this software
     7 * is granted provided this copyright notice appears in all copies.
     8 * This software is provided "as is" without express or implied
     9 * warranty, and with no claim as to its suitability for any purpose.
    10 */
    11 #include <functional>
    12 #include <algorithm>
    13 #include <vector>
    14 #include <iostream>
    15 #include <string>
    16 using namespace std;
    17 using namespace std::placeholders;
    18 
    19 class Person {
    20 private:
    21     string name;
    22 public:
    23     Person(const string& n) : name(n) {
    24     }
    25     void print() const {
    26         cout << name << endl;
    27     }
    28     void print2(const string& prefix) const {
    29         cout << prefix << name << endl;
    30     }
    31     //...
    32 };
    33 
    34 int main()
    35 {
    36     vector<Person> coll
    37         = { Person("Tick"), Person("Trick"), Person("Track") };
    38 
    39     // call member function print() for each person
    40     for_each(coll.begin(), coll.end(),
    41         [](const Person& p) {
    42         p.print();
    43     });
    44     cout << endl;
    45 
    46     // call member function print2() with additional argument for each person
    47     for_each(coll.begin(), coll.end(),
    48         [](const Person& p) {
    49         p.print2("Person: ");
    50     });
    51 }
    View Code
  • 相关阅读:
    IOS5,6,7不同版的适配. 强制旋转和自动旋转.
    第3条:多用字面量语法,少用与之等价的方法
    UIViewAnimation警告
    ViewController的生命周期分析和使用
    Chrome浏览器下调试SASS
    Reactjs相比较原生方案是绝对的快吗?哪些情况下React有优势
    js收集的一些好的题型
    js异步加载 defer和async 比较
    前端知识点
    H5下拉刷新特效demo,动画流畅
  • 原文地址:https://www.cnblogs.com/larry-xia/p/9496343.html
Copyright © 2011-2022 走看看