C++ function 表达式

本文深入探讨了C++中的function包装器,展示了如何使用它来优化函数指针、类对象和lambda表达式的实例化过程,减少重复创建,提高代码效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 提供了多个包装器 ,这些对象用于给其他编程接口提供一致或更好的接口,接下来介绍包装器function及其解决的问题。先看一组代码:

#include <iostream>


template<typename T,typename F>

T use_f(T v, F f)
{
	static int count = 0;
	count++;
	std::cout << " use of 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 p) { return z_+p; }
};

double dub(double x) { return 2.0*x; }
double square(double x) { return x*x; }

 int main()
 {
	using std::cout;
	using std::endl;

	double y = 1.21;
	cout << "Function pointer dub is :" << endl;
	cout << " " << use_f(y, dub) << endl;
	cout << "Function pointer square is :" << endl;
	cout << " " << use_f(y, square) << endl;
	cout << "Function pointer Fp is :" << endl;
	cout << " " << use_f(y, Fp(5.0)) << endl;
	cout << "Function pointer Fq is :" << endl;
	cout << " " << use_f(y, Fq(5.0)) << endl;
	cout << "Lambda experssion " << endl;
	cout << " " << use_f(y, [](double u) {return u*u; }) << endl;
	cout << "Lambda experssion " << endl;
	cout << " " << use_f(y, [](double u) {return u*2; }) << endl;
	
}

程序运行结果如下图所示:

                                             

每次调用中参数F都接受一个double类型的变量,返回一个double 类型的值,看起来只进行一次实例化,但其实不是,通过静态成员变量看出,实例化了五次。

如何解决这个问题,采用function 包装器。代码实例如下:

#include <iostream>
#include <functional>

template<typename T, typename F>

T use_f(T v, F f)
{
	static int count = 0;
	count++;
	std::cout << " use of 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 p) { return z_ + p; }
};

double dub(double x) { return 2.0*x; }
double square(double x) { return x*x; }

int main()
{
	using std::cout;
	using std::endl;
	using std::function;

	double y = 1.21;
	function<double(double)> ef1 = dub;
	function<double(double)> ef2 = square;
	function<double(double)> ef3 = Fp(5);
	function<double(double)> ef4 = Fq(5);
	function<double(double)> ef5 = [](double u) {return u*u; };
	function<double(double)> ef6 = [](double u) {return 2 * u; };

	cout << "Function pointer dub is :" << endl;
	cout << " " << use_f(y, ef1) << endl;
	cout << "Function pointer square is :" << endl;
	cout << " " << use_f(y, ef1) << endl;
	cout << "Function pointer Fp is :" << endl;
	cout << " " << use_f(y, ef3) << endl;
	cout << "Function pointer Fq is :" << endl;
	cout << " " << use_f(y, ef4) << endl;
	cout << "Lambda experssion " << endl;
	cout << " " << use_f(y, ef5) << endl;
	cout << "Lambda experssion " << endl;
	cout << " " << use_f(y, ef6) << endl;

}

运行结果如下:

                                                      

通过结果看出只进行了一次实例化。

代码还可以按照这种方式写:

#include <iostream>
#include <functional>

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 p) { return z_ + p; }
};


double dub(double x) { return 2.0*x; }
double square(double x) { return x*x; }
int main()
{
	using namespace std;	
	double y = 1.25;
	cout << "Function pointer dub is :" << endl;
	cout << " " << use_f<double>(y, dub) << endl;
	cout << "Function pointer square is :" << endl;
	cout << " " << use_f<double>(y, square) << endl;
	cout << "Function pointer Fp is :" << endl;
	cout << " " << use_f<double>(y, Fp(5)) << endl;
	cout << "Function pointer Fq is :" << endl;
	cout << " " << use_f<double>(y, Fq(10)) << endl;
	cout << "Lambda experssion " << endl;
	cout << " " << use_f<double>(y, [](double x) {return x*x; }) << endl;
	cout << "Lambda experssion " << endl;
	cout << " " << use_f<double>(y, [](double x) {return 2 * x; }) << endl;

}

运行结果:

                                                         

### 关于 C++ Lambda 表达式 Lambda 表达式是一种匿名函数,在 C++11 中被引入,它允许开发者在代码中定义小型的、一次性的函数对象。其语法结构如下: ```cpp [capture](parameters) -> return_type { body } ``` - **capture**: 捕获列表,用于捕获外部变量到 lambda 函数的作用域中[^1]。 - **parameters**: 参数列表,类似于普通函数的参数声明。 - **return_type**: 返回类型,默认情况下可以省略,编译器会自动推导返回类型。 - **body**: 函数体。 #### 示例代码 下面是一个简单的例子展示如何使用 lambda 表达式来实现加法操作: ```cpp #include <iostream> #include <functional> int main() { auto add = [](int a, int b) -> int { return a + b; }; // 定义一个lambda表达式 std::cout << "Result: " << add(3, 4) << std::endl; } ``` 在这个例子中,`add` 是一个 lambda 表达式,它接收两个整数作为输入并返回它们的和。 --- ### 关于 `std::function` 头文件及其相关内容 `std::function` 是 C++ 标准库中的一个重要工具类,位于 `<functional>` 头文件下。它的主要作用是用来封装任意可调用目标(如普通函数函数对象、lambda 表达式等),使得这些不同的可调用实体能够统一处理[^2]。 #### 基本概念 `std::function` 的模板参数形式为 `std::function<返回类型(参数类型...)>`,表示它可以存储任何具有相同签名的可调用对象[^4]。 ##### 示例代码 以下展示了如何利用 `std::function` 来保存不同类型的可调用对象: ```cpp #include <iostream> #include <functional> // 普通函数 int multiply(int a, int b) { return a * b; } class Multiplier { public: int operator()(int a, int b) const { return a * b; } }; int main() { // 使用 std::function 存储不同类型的目标 std::function<int(int, int)> func; // 存储普通函数 func = multiply; std::cout << "Multiply result (func): " << func(6, 7) << std::endl; // 存储 lambda 表达式 func = [](int a, int b) { return a * b; }; std::cout << "Multiply result (lambda): " << func(6, 7) << std::endl; // 存储函数对象 Multiplier multiplierObj; func = multiplierObj; std::cout << "Multiply result (functor): " << func(6, 7) << std::endl; } ``` 上述代码片段演示了 `std::function` 如何灵活地支持多种可调用对象的形式,包括普通函数、lambda 表达式以及函数对象。 --- ### 结合 `std::thread` 和 `std::function` 除了单独使用外,`std::function` 还常与其他标准库组件配合工作,比如多线程编程中的 `std::thread`。通过将复杂的回调逻辑封装成 `std::function` 对象传递给线程构造函数,可以使程序设计更加清晰简洁[^3]。 #### 示例代码 这里给出一个多线程场景下的简单应用实例: ```cpp #include <iostream> #include <thread> #include <functional> void threadFunc(const std::string& msg) { std::cout << "Thread says: " << msg << std::endl; } int main() { // 将函数绑定至 std::function 并传入 std::thread 构造函数 std::function<void(const std::string&)> f = threadFunc; std::thread t(f, "Hello from thread!"); t.join(); // 等待子线程完成 } ``` 此案例说明了如何借助 `std::function` 实现更优雅的任务分发机制。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值