【c++修行之路】c++11新特性--下

一、前言

大家好久不见,今天我们继续来学习c++11的新特性。

二、包装器

先来看一段代码:

#include <iostream>

using namespace std;

class sub
{
    
    
public:
	int operator()(int x, int y)
	{
    
    
		return x - y;
	}
};

int add(int x, int y)
{
    
    
	return x + y;
}

int main()
{
    
    
	//函数指针:		1+2=3
	int(*fp)(int, int);
	fp = add;
	cout << fp(1, 2) << endl;

	//仿函数:			4-2=2
	sub s;
	cout << s(4,2) << endl;

	//lambda表达式:	3*3=9
	auto mul = [](int a, int b) -> int {
    
    
		return a * b;
	};
	cout << mul(3, 3) << endl;

	
	return 0;
}

在这段代码里,我分别使用了函数指针、仿函数、lambda表达式来表示加法,减法和乘法的运算,我们知道在C++中存在函数指针、仿函数和lambda表达式等多种方式来表示和使用函数,为什么还要费心费力地搞一个包装器出来呢,以下是我的个人理解:

2.1包装器统一了接口

假如我要将上述的三种运算保存在一个map里,你会发现这面临着重重困难,首先函数指针的类型及其复杂,再者三种运算都使用不同的方式实现,无法统一,也无法保证未来不使用新的方式实现,而包装器可以同时接收函数指针、仿函数、lambda表达式,调用时可以做到统一。

参考代码:

#include <iostream>
#include <string>
#include <map>
#include <functional>
using namespace std;

class sub
{
    
    
public:
	int operator()(int x, int y)
	{
    
    
		return x - y;
	}
};

int add(int x, int y)
{
    
    
	return x + y;
}

int main()
{
    
    
	map<string, function<int(int, int)>> opration_map;
	opration_map =
	{
    
    
		{
    
    "+",add},
		{
    
    "-",sub()},
		{
    
    "*",[](int x,int y)->int {
    
    return x * y;} }
	};
	cout << opration_map["+"](2, 2) << endl; //4
	cout << opration_map["-"](2, 2) << endl; //0
	cout << opration_map["*"](2, 2) << endl; //4
}

2.2使用包装的思想设计包装函数

有了包装的思想,我们可以设计一个包装函数,可以统一管理和调用参数不一致、名称不一样的函数,当然也可以使用类似的思路设计对应的包装类。


#include <iostream>
#include <functional>

void internet_service(string ip,int port) 
{
    
    
    std::cout << "启动网络服务" << std::endl;
    std::cout << "ip为:"  << ip <<std::endl;
    std::cout << "端口号为:" << port <<std::endl;
}

void process_service(int id) {
    
    
    std::cout << "启动进程" << std::endl;
    std::cout << "进程id:" << id <<std::endl;
}

// 统一接口的包装器函数
template<typename Func, typename... Args>
void execute(Func func, Args... args) 
{
    
    
    cout << "正在统一记录日志" << endl;
    func(args...); // 调用原始函数
    cout << "正在进行统一清理工作" << endl;
}

int main() 
{
    
    
    // 统一调用不同类型的函数
    execute(internet_service, "127.0.0.1",8080); 
    execute(process_service,114514);

    return 0;
}

三、绑定(bind)

3.1调整参数顺序

使用bind可以调整函数的参数顺序,实例如下:

void Print(int x,int y)
{
    
    
	cout << "第一个参数:" << x << endl;
	cout << "第二个参数:" << y << endl;
}

int main()
{
    
    
	bind(Print, placeholders::_1, placeholders::_2)(1, 2);
	bind(Print, placeholders::_2, placeholders::_1)(1, 2);

	return 0;
}

3.2调整参数个数

我们知道类中的函数默认会带一个参数:this指针,这就会给我们的包装器带来诸多麻烦,因为又要去解决类型不一致的问题,恰巧bind能够帮助我们解决这个问题:

class sub
{
    
    
public:
	int func(int x, int y)
	{
    
    
		return x - y;
	}
};

int main()
{
    
    
	sub s;
	function<int(sub,int, int)> fsub1 = &sub::func;
	function<int(int, int)> fsub2 = bind(&sub::func, sub(), placeholders::_1, placeholders::_2);
	function<int(int, int)> fsub3 = bind(&sub::func, &s, placeholders::_1, placeholders::_2);

	cout << fsub1(sub(), 2, 1) << endl;
	cout << fsub2(2, 1) << endl;
	cout << fsub3(2, 1) << endl;
	return 0;
}

可以看到bind将第一个参数写死来减少实际需要我们传递的参数个数,可以看到使用bind无论是匿名对象还是实例指针都是可以成功绑定的,但第一种我们在调用的时候只能传递类的对象,因此更推荐第二种方式。

扫描二维码关注公众号,回复: 15955261 查看本文章

四、结语

到这里,关于c++11新特性的相关讲解就告一段落了,两篇文章间隔较长,主要是中间去做课设了,不过好在课设拿了95分,也算没白浪费时间,接下来会持续更新c++和Linux以及MySQL的相关知识,我们下期再见!

猜你喜欢

转载自blog.csdn.net/m0_73209194/article/details/131038799