C++11包装器

编程入门 行业动态 更新时间:2024-10-09 19:18:23

C++11包装器

C++11包装器

文章目录

  • 1.当前程序的问题
  • 2.包装器的引入
    • 2.1包装器的定义
    • 2.2包装器的使用
    • 2.3包装器的出现对于2.1问题的解决
  • 3.包装器的应用
    • 3.1C++98写法
    • 3.2C++11写法
      • count()的用法
      • 下标运算符operator[ ]
      • lambda表达式的另一种用法
      • C++11写法

1.当前程序的问题

template<class T, class K>
K useFun(T fun, K x)
{//count是一个static对象 当这个函数结束 count不会被销毁static int count = 0;//每次使用这个函数 输出count+1的值 //如果是同一个函数 count会输出1 2 3//而运行结果是 1 1 1 说明这个函数模板被实例化成3个不同的函数cout << "count:" << ++count << endl;//每次使用这个函数 输出count的地址cout << "count:" << &count << endl;return fun(x);//fun可能是一个函数名\函数指针\函数对象\lambda表达式
}int func(int x)
{return x;
}struct Functor
{int operator()(int x){return x;}
};int main()
{// 函数指针cout << useFun(func, 1) << endl;// 函数对象cout << useFun(Functor(), 2) << endl;// lamber表达式对象auto ret = useFun([](int x)->int{return x;}, 3);cout << ret << endl;return 0;
}

通过运行结果我们可以看到useFun函数模板被实例化了三份
在useFun函数模板中 count是一个static对象
当这个函数结束 count不会被销毁
每次使用这个函数 输出count+1的值
如果是同一个函数 count会输出1 2 3
而运行结果是 1 1 1 说明这个函数模板被实例化成3个不同的函数
通过count的地址也可以看出这是三个不同的count

问题来了 怎么能让useFun函数模板不被实例化成3份呢?这是包装器的作用就显现出来了

2.包装器的引入

2.1包装器的定义

#include<functional>
// 类模板原型如下
template <class T> 
function;template <class Ret, class... Args>
class function<Ret(Args...)>;
模板参数说明:
Ret: 被调用函数的返回类型
Args…:被调用函数的形参

2.2包装器的使用

int fun(int a, int b)
{return a + b;
}struct Functor
{
public:int operator() (int a, int b){return a + b;}
};class PLus
{
public:static int plus_int(int a, int b){return a + b;}double plus_double(double a, double b){return a + b;}
};int main()
{function<int(int, int)> f1 = fun;cout << f1(1, 2) << endl;function<int(int, int)> f2 = Functor();cout << f2(1, 2) << endl;//静态成员函数通过类名直接访问方式function<int(int, int)> f3 = PLus::plus_int;cout << f3(1, 2) << endl;//非静态成员函数通过类名直接访问方式function<double(PLus,double, double)> f4 = &PLus::plus_double;f4(PLus(), 1.1, 2.2);return 0;
}

2.3包装器的出现对于2.1问题的解决

template<class T, class K>
T useFun(K fun, T x)
{staic int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return fun(x);
}int func(int x)
{return x;
}struct Functor
{int operator()(int x){return x;}
};int main()
{// 函数指针function<int(int)> f1 = func;cout << useFun(f1, 1) << endl;// 函数对象function<int(int)> f2 = Functor();cout << useFun(f2, 2) << endl;// lamber表达式对象function<int(int)> f3 = [](int x)->int {return x; };cout << useFun(f3, 3) << endl;return 0;
}

3.包装器的应用

逆波兰表达式求值

3.1C++98写法

class Solution 
{
public://Evaluate inverse Polish notationint evalRPN(vector<string>& tokens){stack<long long> st;for (auto& str : tokens){if (str == "+" || str == "-" || str == "*" || str == "/" ){long long right = st.top();st.pop();long long left = st.top();st.pop();switch (str[0]){case '+':st.push(left + right);break;case '-':st.push(left - right);break;case '*':st.push(left * right);break;case '/':st.push(left / right);break;}}else{st.push(stoll(str));}}return st.top();}
};

3.2C++11写法

count()的用法

如果容器包含键等于k的元素,则为1,否则为零。成员类型size_type是一个无符号整数类型。

下标运算符operator[ ]

如果k与容器中某个元素的键匹配,则函数将返回对其映射值的引用。如果k与容器中任何元素的键都不匹配,则函数将插入一个具有该键的新元素,并返回对其映射值的引用。请注意,即使没有为元素分配映射值(该元素是使用其默认构造函数构造的),这也会使容器大小增加一。类似的成员函数map::at在具有键的元素存在时具有相同的行为,但在不存在时抛出异常。

lambda表达式的另一种用法

template<class T, class K>
T useFun(K fun, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "&count:" << &count << endl;return fun(x);
}int func(int x)
{return x;
}struct Functor
{int operator()(int x){return x;}
};int main()
{// 函数指针function<int(int)> f1 = func;cout << "func(1) == " << func(1) << endl; cout << useFun(f1, 1) << endl;cout << endl;// 函数对象function<int(int)> f2 = Functor();cout << "Functor()(1) == " << Functor()(1) << endl;cout << useFun(f2, 2) << endl;cout << endl;// lamber表达式对象function<int(int)> f3 = [](int x)->int {return x; };cout << "[](int x)->int {return x; }(1) == " << [](int x)->int {return x; }(1) << endl;cout << useFun(f3, 3) << endl;return 0;
}

C++11写法

class Solution
{typedef long long Long;
public:int evalRPN(vector<string>& tokens){stack<Long> st;//m初始化时 插入4个数据 //key分别是 + - * ///value是lambda表达式 //分别是对应key所能进行的运算map< string, function<Long(Long, Long)> > m ={{"+", [](Long a, Long b) { return a + b; }},{"-", [](Long a, Long b) { return a - b; }},{"*", [](Long a, Long b) { return a * b; }},{"/", [](Long a, Long b) { return a / b; }}};for (auto& e : tokens){//m中只存储了+-*/四个字符 //所以对于tokens中的数字count返回0//对于运算符返回1//是运算符if (m.count(e)){Long right = st.top();st.pop();Long left = st.top();st.pop();//m[e]: m将e作为key值去查找 返回e对应的valuest.push(m[e](left, right));}//是数字elsest.push(stoll(e));}return st.top();}
};

更多推荐

C++11包装器

本文发布于:2023-12-06 23:35:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1669358.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!