C++ 包装器,看这一篇就够了

C++ 包装器

1 简介

包装器用于给其他编程接口提供更一致或更合适的接口。

  • 模板bind可替代bind1st和bind2nd,且更灵活
  • 模板mem_fn让您能够将成员函数作为常规函数进行传递
  • 模板reference_wrapper让您能够创建像引用但可被复制的对象
  • 包装器function让您能够以统一的方式处理多种类似于函数的形式

模板function是在头文件functional头文件中声明的,他从参数和返回值的角度定义了一个对象,可用于包装调用参数和返回值相同的函数指针、伪函数或lambda表达式

2 为什么使用包装器

由于函数调用可以使用函数名、函数指针、函数对象或有名称的lambda表达式,可调用类型太丰富导致模板的效率极低。

包装器用于解决效率低的问题。

3 测试与对比

3.1 普通版本与优化版本

3.1.1 代码

somedefs.h

#pragma once
// somedefs.h
#include <iostream>
template <typename T, typename F>
T use_f(T v, F f)
{
	static int count = 0;
	count++;
	std::cout << " use_f count = " << count
		<< ", &count = " << &count << std::endl;
	return f(v);
}
class Fp
{
private:
	double z_;
public:
	Fp(double z = 1.0) : z_(z) {}
	double operator()(double p) { return z_ * p; }
};
class Fq
{
private:
	double z_;
public:
	Fq(double z = 1.0) : z_(z) {}
	double operator()(double q) { return z_ + q; }
};

main.cpp

/*
Project name :			_2OWrappers
Last modified Date:		2022年5月6日10点09分
Last Version:			V1.0
Descriptions:			包装器
*/
#include "somedefs.h"
#include <iostream>
#include <functional>
double dub(double x) { return 2.0 * x; }
double square(double x) { return x * x; }
int main()
{
	using namespace std;
	double y = 1.21;
	//此处实例化了五个use_f模板函数,导致编译代码多,效率低
	cout << "普通版本******************************************************" << endl;
	cout << "Function pointer dub:\n";
	cout << " " << use_f(y, dub) << endl;
	cout << "Function pointer square:\n";
	cout << " " << use_f(y, square) << endl;
	cout << "Function object Fp:\n";
	cout << " " << use_f(y, Fp(5.0)) << endl;
	cout << "Function object Fq:\n";
	cout << " " << use_f(y, Fq(5.0)) << endl;
	cout << "Lambda expression 1:\n";
	cout << " " << use_f(y, [](double u) {return u * u; }) << endl;
	cout << "Lambda expression 2:\n";
	cout << " " << use_f(y, [](double u) {return u + u / 2.0; }) << endl;
	cout << "优化版本******************************************************" << endl;
	//考虑到上述函数的参数和返回值(call signature)都为 double(double),
	//因此使用function<double(double)>装饰它创建六个包装器,实现只实例化一个use_f函数模板
	function<double(double)> ef1 = dub;
	function<double(double)> ef2 = square;
	function<double(double)> ef3 = Fq(10.0);
	function<double(double)> ef4 = Fp(10.0);
	function<double(double)> ef5 = [](double u) {return u * u; };
	function<double(double)> ef6 = [](double u) {return u + u / 2.0; };
	cout << "Function pointer dub:\n";
	cout << " " << use_f(y, ef1) << endl;
	cout << "Function pointer square:\n";
	cout << " " << use_f(y, ef2) << endl;
	cout << "Function object Fp:\n";
	cout << " " << use_f(y, ef3) << endl;
	cout << "Function object Fq:\n";
	cout << " " << use_f(y, ef4) << endl;
	cout << "Lambda expression 1:\n";
	cout << " " << use_f(y, ef5) << endl;
	cout << "Lambda expression 2:\n";
	cout << " " << use_f(y, ef6) << endl;
	
	return 0;
}

3.1.2 运行结果

普通版本******************************************************
Function pointer dub:
 use_f count = 1, &count = 00007FF6DD7436D0
 2.42
Function pointer square:
 use_f count = 2, &count = 00007FF6DD7436D0
 1.4641
Function object Fp:
 use_f count = 1, &count = 00007FF6DD7436D4
 6.05
Function object Fq:
 use_f count = 1, &count = 00007FF6DD7436D8
 6.21
Lambda expression 1:
 use_f count = 1, &count = 00007FF6DD7436DC
 1.4641
Lambda expression 2:
 use_f count = 1, &count = 00007FF6DD7436E0
 1.815
优化版本******************************************************
Function pointer dub:
 use_f count = 1, &count = 00007FF6DD7436E8
 2.42
Function pointer square:
 use_f count = 2, &count = 00007FF6DD7436E8
 1.4641
Function object Fp:
 use_f count = 3, &count = 00007FF6DD7436E8
 11.21
Function object Fq:
 use_f count = 4, &count = 00007FF6DD7436E8
 12.1
Lambda expression 1:
 use_f count = 5, &count = 00007FF6DD7436E8
 1.4641
Lambda expression 2:
 use_f count = 6, &count = 00007FF6DD7436E8
 1.815

D:\Prj\_C++Self\_34Wrappers\x64\Debug\_34Wrappers.exe (进程 1132)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

3.2 最优化版本

3.2.1 代码

somedefs.h

#pragma once
#include <iostream>
#include <functional>
//使用function模板
template <typename T>
T use_f(T v, std::function<T(T)> f)
{
	static int count = 0;
	count++;
	std::cout << " use_f count = " << count
		<< ", &count = " << &count << std::endl;
	return f(v);
}
class Fp
{
private:
	double z_;
public:
	Fp(double z = 1.0) : z_(z) {}
	double operator()(double p) { return z_ * p; }
};
class Fq
{
private:
	double z_;
public:
	Fq(double z = 1.0) : z_(z) {}
	double operator()(double q) { return z_ + q; }
};

main.cpp

/*
Project name :			_2OWrappers_optimization
Last modified Date:		2022年5月6日10点30分
Last Version:			V1.0
Descriptions:			包装器最优化
*/
#include "somedefs.h"

double dub(double x) { return 2.0 * x; }
double square(double x) { return x * x; }
int main()
{
	using namespace std;
	double y = 1.21;
	typedef function<double(double)> fdd; // simplify the type declaration
	cout << "Function pointer dub:\n";
	cout << use_f(y, fdd(dub)) << endl; // create and initialize object to dub
	cout << "Function pointer square:\n";
	cout << use_f(y, fdd(square)) << endl;
	cout << "Function object Fp:\n";
	cout << use_f(y, fdd(Fp(5.0))) << endl;
	cout << "Function object Fq:\n";
	cout << use_f(y, fdd(Fq(5.0))) << endl;
	cout << "Lambda expression 1:\n";
	cout << use_f(y, fdd([](double u) {return u * u; })) << endl;
	cout << "Lambda expression 2:\n";
	cout << use_f(y, fdd([](double u) {return u + u / 2.0; })) << endl;
	return 0;
}

3.2.2 运行结果

Function pointer dub:
 use_f count = 1, &count = 00007FF7172836D0
2.42
Function pointer square:
 use_f count = 2, &count = 00007FF7172836D0
1.4641
Function object Fp:
 use_f count = 3, &count = 00007FF7172836D0
6.05
Function object Fq:
 use_f count = 4, &count = 00007FF7172836D0
6.21
Lambda expression 1:
 use_f count = 5, &count = 00007FF7172836D0
1.4641
Lambda expression 2:
 use_f count = 6, &count = 00007FF7172836D0
1.815

D:\Prj\_C++Self\_33Wrapper_optimization\x64\Debug\_33Wrapper_optimization.exe (进程 1036)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .

4 README

此为本人读C++ Primer总结的笔记,如有错误或知识缺口,请在评论区告知。如本文有在实践中帮到您,是本人的荣幸。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jasmine-Lily

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值