前文
function包装器
标签:11,function,return,cout,包装,C++,st,int,str From: https://blog.csdn.net/2301_76618602/article/details/1404153461.概念
目前我们知道的可调用对象有:函数指针(类型定义太复杂),仿函数对象(要定义一个类,用的时候有点麻烦,不适合做类型统一),lambda(没有类型概念),所以引出了一个新的东西:包装器。
function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。用来包装可调用对象
function类重载operator(),本质上也是一个仿函数。
2.用法
类模板原型如下:
std::function在头文件<functional> template <class T> function; // undefined template <class Ret, class... Args> class function<Ret(Args...)>; //模板参数说明: //Ret: 被调用函数的返回类型 //Args…:被调用函数的形参
ret = func(x);
上面func可能是什么呢?那么func可能是函数名?函数指针?函数对象(仿函数对象)?也有可能是lamber表达式对象?所以这些都是可调用的类型!如此丰富的类型,可能会导致模板的效率低下!为什么呢?我们继续往下看静态成员变量在对象实例化的时候才会初始化,下面类模板实例化了三个类型就初始化了三次,这就导致了模板效率低下。
template<class F, class T> T useF(F f, T x) { static int count = 0; cout << "count:" << ++count << endl; cout << "count:" << &count << endl; return f(x); } double f(double i) { return i / 2; } struct Functor { double operator()(double d) { return d / 3; } }; int main() { // 函数名 cout << useF(f, 11.11) << endl; // 函数对象 cout << useF(Functor(), 11.11) << endl; // lamber表达式 cout << useF([](double d)->double { return d / 4; }, 11.11) << endl; return 0; }
使用function解决:统一了类型,实例化一次就行了这就提高了效率。
#include <functional> template<class F, class T> T useF(F f, T x) { static int count = 0; cout << "count:" << ++count << endl; cout << "count:" << &count << endl; return f(x); } double f(double i) { return i / 2; } struct Functor { double operator()(double d) { return d / 3; } }; int main() { // 函数名 std::function<double(double)> func1 = f; cout << useF(func1, 11.11) << endl; // 仿函数 std::function<double(double)> func2 = Functor(); cout << useF(func2, 11.11) << endl; // lamber表达式 std::function<double(double)> func3 = [](double d)->double { return d / 4; }; cout << useF(func3, 11.11) << endl; return 0; }
下面是一段示例:封装了函数调用,仿函数,lamber表达式,类的成员函数。
#include<functional> int f(int a, int b) { return a + b; } struct Functor { public: int operator() (int a, int b) { return a + b; } }; class Plus { public: static int plusi(int a, int b) { return a + b; } double plusd(double a, double b) { return a + b; } }; int main() { // 函数名(函数指针) std::function<int(int, int)> func1 = f; cout << func1(1, 2) << endl; // 仿函数 std::function<int(int, int)> func2 = Functor(); cout << func2(1, 2) << endl; // lamber表达式 std::function<int(int, int)> func3 = [](const int a, const int b) {return a + b; }; cout << func3(1, 2) << endl; // 类的成员函数 std::function<int(int, int)> func4 = &Plus::plusi; cout << func4(1, 2) << endl; std::function<double(Plus, double, double)> func5 = &Plus::plusd; //匿名对象 cout << func5(Plus(), 1.1, 2.2) << endl; return 0; }
3.来看一道题目:力扣--150.逆波兰表达式求值
思路:操作符运算,操作数入栈。
class Solution { public: int evalRPN(vector<string>& tokens) { stack<int> s; for (size_t i = 0; i < tokens.size(); ++i) { string& str = tokens[i]; // str为数字 if (!("+" == str || "-" == str || "*" == str || "/" == str)) { s.push(atoi(str.c_str())); } else { // str为操作符 int right = s.top(); s.pop(); int left = s.top(); s.pop(); switch (str[0]) { case '+': s.push(left + right); break; case '-': s.push(left - right); break; case '*': s.push(left * right); break; case '/': s.push(left / right); break; } } } return s.top(); } };
使用包装器:加减乘除自动匹配
class Solution { public: int evalRPN(vector<string>& tokens) { stack<int> st; map<string, function<int(int, int)>> opFuncMap = { { "+", [](int i, int j) {return i + j; } }, { "-", [](int i, int j) {return i - j; } }, { "*", [](int i, int j) {return i * j; } }, { "/", [](int i, int j) {return i / j; } } }; for (auto& str : tokens) { if (opFuncMap.find(str) != opFuncMap.end()) { int right = st.top(); st.pop(); int left = st.top(); st.pop(); st.push(opFuncMap[str](left, right)); } else { // 1、atoi itoa // 2、sprintf scanf // 3、stoi to_string C++11 st.push(stoi(str)); } } return st.top(); } };