六一的部落格


关关难过关关过,前路漫漫亦灿灿。



必须作为成员函数

如果为类类型重载了函数调用运算符 () , 可以像使用函数一样使用对象: 对其使用调用运算符, 并传入参数, 调用重载的调用运算符

重载了调用运算符的类对象使用起来比函数更灵活, 因为可以使用数据成员来存储状态

如果类定义调用运算符, 则该类的对象也称作函数对象 function object

调用运算符可有多个重载版本


用于打印的函数对象

 1class PrintString
 2{
 3public:
 4    PrintString(ostream &o = cout, char c = ' ') : os(o), sep(c) {}
 5    void operator() (const string &s) const { os << s << sep; }
 6private:
 7    ostream &os;
 8    char sep;
 9};
10
11PrintString printer;
12printer(s);
13PrintString errors(cerr, '\n');
14errors(s);

函数对象常常作为泛型算法的实参

1for_each(vs.begin(), vs.end(), PrintString(cerr, '\n'));

lambda是函数对象

lambda表达式产生的类不含默认构造函数, 赋值运算符和默认析构函数; 是否含有默认的拷贝/移动构造函数视捕获的数据成员类型而定

书上指出lambda表达式为未命名类的未命名对象, 但并未清楚说明lambda表达式的实现


标准库定义的函数对象

模板类

我们惯常使用运算符, 但用作泛型算法的参数, 得给出名称


头文件

1#include <functional>

算术运算

-
plus<T>
minus<Type>
multiplies<Type>
divides<Type>
modulus<T> 取余
negate<T>
1plus<int> intAdd;
2negate<int> intNegate;
3int sum = intAdd(10, 20);
4sum = intNegate(intAdd(10, 20));
5sum = intAdd(10, intNegate(10));

关系运算

-
equal_to<T> 相等
not_equal_to<Type>
greater<Type>
greater_equal<Type>
less<Type>
less_equal<Type>

示例

  1. 泛型算法: 排序
    1sort(svec.begin(), svec.end(), greater<string>());        // 从大到小
    
  2. 关联容器: 关键字排序
    1vector<string *> nameTable;                                                                  // nameTable保存string指针
    2sort(nameTable.begin(), nameTable.end(), [](string *a, string *b) { return a < b; });        // 使用内置的<会产生未定义行为
    3sort(nameTable.begin(), nameTable.end(), less<string *>());                                  // 标准库的less类对于指针有良好定义,可以比较指针的地址
    4
    5// 关联容器使用的就是less<KType>对元素排序,所以关联容器保存指针时,元素仍有序
    

逻辑关系

-
logical_and<Type>
logical_or<Type>
logical_not<Type> 逻辑非

运算符重载: 函数调用运算符


必须作为成员函数

如果为类类型重载了函数调用运算符 () , 可以像使用函数一样使用对象: 对其使用调用运算符, 并传入参数, 调用重载的调用运算符

重载了调用运算符的类对象使用起来比函数更灵活, 因为可以使用数据成员来存储状态

如果类定义调用运算符, 则该类的对象也称作函数对象 function object

调用运算符可有多个重载版本


用于打印的函数对象

 1class PrintString
 2{
 3public:
 4    PrintString(ostream &o = cout, char c = ' ') : os(o), sep(c) {}
 5    void operator() (const string &s) const { os << s << sep; }
 6private:
 7    ostream &os;
 8    char sep;
 9};
10
11PrintString printer;
12printer(s);
13PrintString errors(cerr, '\n');
14errors(s);

函数对象常常作为泛型算法的实参

1for_each(vs.begin(), vs.end(), PrintString(cerr, '\n'));

lambda是函数对象

lambda表达式产生的类不含默认构造函数, 赋值运算符和默认析构函数; 是否含有默认的拷贝/移动构造函数视捕获的数据成员类型而定

书上指出lambda表达式为未命名类的未命名对象, 但并未清楚说明lambda表达式的实现


标准库定义的函数对象

模板类

我们惯常使用运算符, 但用作泛型算法的参数, 得给出名称


头文件

1#include <functional>

算术运算

-
plus<T>
minus<Type>
multiplies<Type>
divides<Type>
modulus<T> 取余
negate<T>
1plus<int> intAdd;
2negate<int> intNegate;
3int sum = intAdd(10, 20);
4sum = intNegate(intAdd(10, 20));
5sum = intAdd(10, intNegate(10));

关系运算

-
equal_to<T> 相等
not_equal_to<Type>
greater<Type>
greater_equal<Type>
less<Type>
less_equal<Type>

示例

  1. 泛型算法: 排序
    1sort(svec.begin(), svec.end(), greater<string>());        // 从大到小
    
  2. 关联容器: 关键字排序
    1vector<string *> nameTable;                                                                  // nameTable保存string指针
    2sort(nameTable.begin(), nameTable.end(), [](string *a, string *b) { return a < b; });        // 使用内置的<会产生未定义行为
    3sort(nameTable.begin(), nameTable.end(), less<string *>());                                  // 标准库的less类对于指针有良好定义,可以比较指针的地址
    4
    5// 关联容器使用的就是less<KType>对元素排序,所以关联容器保存指针时,元素仍有序
    

逻辑关系

-
logical_and<Type>
logical_or<Type>
logical_not<Type> 逻辑非