首页 > 编程语言 >C++11 包装器

C++11 包装器

时间:2024-07-18 22:26:59浏览次数:26  
标签:11 function return cout 包装 C++ st int str

前文

C++11 lambda表达式-CSDN博客

C++11 新的类功能&&可变参数模板-CSDN博客

C++11 右值引用和移动语义-CSDN博客


function包装器

1.概念

        目前我们知道的可调用对象有:函数指针(类型定义太复杂),仿函数对象(要定义一个类,用的时候有点麻烦,不适合做类型统一),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();
	}
};

标签:11,function,return,cout,包装,C++,st,int,str
From: https://blog.csdn.net/2301_76618602/article/details/140415346

相关文章

  • 习题3.11 表达式转换
    算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。输入格式:输入在一行中给出不含空格的中缀表达式,可包含+、-、*、/以及左右括号(),表达式不超过20个......
  • 初识c++:类和对象(4)
    本文大纲:1.再探构造函数(1)之前我们实现构造函数时,初始化成员变量主要使⽤函数体内赋值,构造函数初始化还有⼀种⽅式,就是初始化列表,初始化列表的使⽤⽅式是以⼀个冒号开始,接着是⼀个以逗号分隔的数据成员列表,每个"成员变量"后⾯跟⼀个放在括号中的初始值或表达式。(初始化列表......
  • 实验3-11 计算油费
    现在90号汽油6.95元/升、93号汽油7.44元/升、97号汽油7.93元/升。为吸引顾客,某自动加油站推出了“自助服务”和“协助服务”两个服务等级,分别可得到5%和3%的折扣。本题要求编写程序,根据输入顾客的加油量a,汽油品种b(90、93或97)和服务类型c(m-自助,e-协助),计算并输出应付款。输......
  • C++基础-引用详解(全网最详细,看这篇就够了)
    目录前言一、引用的概念二、引用的特性三、常引用四、引用的使用场景4.1引用做参数4.2引用做返回值五、传值、传引用效率比较5.1值和引用的作为返回值类型的性能比较5.2值和引用作为参数传递之间的性能差别六、引用和指针的区别结束语前言本节我们正式进入C++......
  • 【C++】内联函数
    目录前言一、内联函数的概念二、内联函数的特征三、总结:四、如何在vs2022查看反汇编以及debug模式下查看inline反汇编需要调整的配置。4.1查看反汇编4.1debug模式下查看inline反汇编需要调整的配置结尾前言各位友友好,我们又见面了!本节我们将进入C++基......
  • GESP编程能力等级认证C++编程真题解析 | 2024年3月五级
    学习C++从娃娃抓起!记录下CCF-GESP备考学习过程中的题目,记录每一个瞬间。附上汇总贴:GESP编程能力等级认证C++编程真题解析|汇总单选题第1题唯一分解定理描述的内容是()?A.任意整数都可以分解为素数的乘积B.每个合数都可以唯一分解为一系列素数的乘积C.两个不同的......
  • 白骑士的C++教学实战项目篇 4.3 多线程网络服务器
    系列目录上一篇:白骑士的C++教学实战项目篇4.2学生成绩管理系统        在这一节中,我们将实现一个多线程网络服务器项目,通过该项目,我们将学习套接字编程的基础知识以及如何使用多线程处理并发连接。此外,我们还将实现一个简单的客户端来与服务器进行通信。项目简介......
  • c++ primer plus 第16章string 类和标准模板库,16.2.1 使用智能指针
    c++primerplus第16章string类和标准模板库,16.2.1使用智能指针c++primerplus第16章string类和标准模板库,16.2.1使用智能指针文章目录c++primerplus第16章string类和标准模板库,16.2.1使用智能指针16.2.3uniqueptr为何优于autoptr16.2.3unique......
  • c++ primer plus 第16章string 类和标准模板库,16.2.2 有关智能指针的注意事项
    c++primerplus第16章string类和标准模板库,16.2.2有关智能指针的注意事项c++primerplus第16章string类和标准模板库,16.2.2有关智能指针的注意事项文章目录c++primerplus第16章string类和标准模板库,16.2.2有关智能指针的注意事项16.2.2有关智能指针的......
  • C++ 面向对象程序设计 ---- 类2重点
    1.构造函数,代替Init()函数构造函数的特点1.函数名与类名相同2.无返回值,void也不需要写3.对象实例化时,系统会自动调用构造函数4.构造函数可以重载classDate{public://函数名与类名相同,无返回值Date()//函数重载,无参{_year=1;......