14.8 Function-Call Operator(函数调用操作符)
类中重载调用操作符,允许使用对象就好像函数一样。
#include <iostream> using namespace std; class A { public: int operator()(int k) { (k > 0) || (k = -k);//前者能判断整体真,后者不再执行,不能就继续执行 return k; } private: int a; }; int main() { A a; cout << a(-15) << endl; cout << a(10) << endl; system("PAUSE"); return 0; }
函数调用操作符必须是一个成员函数。一个类可能定义多个版本的调用操作符,每一个必须要有不同数量或者类型的参数。
#include <bits/stdc++.h> using namespace std; class PrintString { public: PrintString(ostream &os = cout, char c = ' '): o(os), s(c){} int operator()(int value)const { return value < 0 ? -value : value; } void operator()(string val) { o << val << s; } private: ostream &o; char s; }; int main() { PrintString A; int n = A(5); cout << n << endl; PrintString print; print("hello-world"); PrintString errors(cerr, '\n'); errors("biubiubiu"); vector<string> vec = { "hi", "ne", "ee", "ai" }; for_each(vec.begin(), vec.end(), PrintString(cerr, '\n')); system("PAUSE"); return 0; }
#include <bits/stdc++.h> using namespace std; class PrintStr { public: PrintStr(istream &in = cin):in(cin){} string& operator()() { if (getline(in, line)) return line; line = " "; return line; } private: istream& in; string line; }; int main() { PrintStr A; string temp; while ( (temp = A()) != " " ) { cout << A(); } system("PAUSE"); return 0; }
#include <bits/stdc++.h> using namespace std; class PrintStr { public: PrintStr(istream &in = cin) :in(cin) {} vector<string>* operator()() { if (getline(in, line)) { vec.push_back(line); return &vec; } line = " "; vec.push_back(line); return &vec; } private: istream& in; string line; vector<string> vec; }; int main() { PrintStr A; vector<string> vec; while (*((vec = *A()).end() - 1) != " "); for (auto &i : vec) { cout << i << endl; } system("PAUSE"); return 0; }
当我们写一个lambdas时,编译器翻译表达式为一个未命名类的未命名对象。
如果lambdas声明为mutable,调用的操作符是非const。
find_if第三个参数接受一个范围,范围内的对象是否满足函数中的条件,返回一个bool值,找不到时返回end或者0
#include <bits/stdc++.h> using namespace std; class Sortvec { public: bool operator()(const string &str1, const string &str2) { return str1.size() < str2.size();//从小到大排序 } }; int main() { vector<string> vec = { "hello", "ni", "zhu", "aaa", "b", "bb" }; stable_sort(vec.begin(), vec.end(), [](const string &str1, const string &str2)->bool{ return str1.size() > str2.size(); });//大到小排序 for (auto &i : vec) { cout << i << " "; } cout << endl; stable_sort(vec.begin(), vec.end(), Sortvec()); for (auto &i : vec) { cout << i << " "; } system("PAUSE"); return 0; }
库函数定义对象:定义在functional头文件
| 算术 | 关系 | 逻辑 |
| plus<Type> | equal_to<Type> | logical_and<Type> |
| minus<Type> | not_equal_to<Type> | logical_or<Type> |
| multiplies<Type> | greater<Type> | logical_not<Type> |
| divides<Type> | greater_equal<Type> | |
| modulus<Type> | less<Type> | |
| negate<Type> | less_equal<Type> |
C++有几种可调用对象:函数和指向函数的指针,lambdas(匿名函数),通过bind创造的对象,重载函数调用操作符的类。
一个调用签名对应一个函数类型:int(int, int)
#include <iostream> #include <map> #include <string> using namespace std; int add(int i, int j) { return i + j; } auto mod = [](int i, int j)->int {return i % j; }; struct divide { int operator()(int i, int j) { return i / j; } }; int main() { map<string, int(*)(int, int)> mp; mp.insert({ "+", add }); mp.insert({ "%", mod });//按标准为错误,mod不是一个指针指向函数 cout << mp["%"](5, 2); system("PAUSE"); return 0; }
mod是一个lambda,每个lambda都有自己匹配的类类型,和map中存储类型不匹配。
#include <iostream> #include <string> #include <vector> #include <map> #include <functional> using namespace std; int add(int i, int j) { return i + j; } int multiply(int i, int j) { return i * j; } auto mod = [](int i, int j)->int { return i % j; }; class divide { public: double operator()(double i, double j) { return i / j; } }; int main() { //int(int, int) map<char, function<double(double, double)>> calculator = { { '+', add }, { '%', mod }, { '/',divide() }, {'-', minus<int>()} }; calculator.insert({ '*', multiply }); calculator.insert({ '^', [](int i, int j)->int { return pow(i, j); } }); double a, b; char s; while (cin >> a >> s >> b) { cout << a << s << b << "=" << calculator[s](a, b) << endl; } std::system("PAUSE"); return 0; }
在新的库中类function和类名unary_function和binary_function是没有关系的。这些函数已经被弃用,用普通的bind来替代。

浙公网安备 33010602011771号