C++函数指针和模板

本文详细介绍了C++中的函数指针声明、使用,以及如何与函数模板结合。通过实例展示了如何定义和调用函数指针,以及如何使用函数模板实现泛型编程。此外,还探讨了默认模板参数在类模板和函数模板中的应用,以及可调用对象在模板中的使用情况。

一、函数指针声明

//函数原型
double sum(double,double);
//函数指针的声明
double (*ptrSum)(double,double)

注意:
1,该语句声明了一个指针ptrSum,指向一个函数。
2,double *ptrSum(double,double) 不是函数指针 而是:声明一个函数,返回值为double *类型(指针函数)。
3,需要先定义函数,然后再定义函数指针。

//定义一个函数指针类型
typedef int (*FuncType)(int, int);	
using FuncType = int (*)(int, int);	//用using 定义别名
//定义一个普通函数
int Func(int a, int b)
{
	return a + b;
}
void TestFunc(int a, int b, FuncType p)	//p 就是函数指针 等价于int (*FuncType)(int, int);
{
	//通过函数指针调用函数
	cout << p(a, b) << endl;
}
int main()
{
	TestFunc(10, 25, Func);
	
	return 0;
}

二、用函数模板和函数指针结合

1. 函数指针形式

//定义一个函数指针类型
typedef int (*FuncType)(int, int);
//定义一个普通函数
int Func(int a, int b)
{
	return a + b;
}
//定义函数模板
template<typename T, typename F>
void TestFunc(const T& a, const T& b, F func)
{
	cout << func(a, b) << endl;
}
int main()
{
	TestFunc<int, FuncType>(25, 35, Func);	//TestFunc(25, 35, Func);也可以,编译器会自动推断类型
	return 0;
}

2. 可调用对象形式

class Test 
{
public:
	Test() { cout << "构造函数执行" << endl; }
	Test(const Test& test) { cout << "拷贝构造函数执行" << endl; }
	//重载圆括号
	int operator()(int a, int b) const
	{
		return a + b;
	}
};
int main()
{
	Test test;
	TestFunc<int, Test>(25, 35, test);	//可调用对象 会调用拷贝构造函数
	TestFunc<int, Test>(25, 35, Test());	//不会调用拷贝构造函数
	return 0;
}

三、默认模板参数

1. 类模板

类模板名后面必须用<>来提供额外信息。<>表示这是一个模板。

template<typename T = string, int size = 10>
class Array
{
public:
	void Func();
private:
	T arr[size];
};

template<typename T, int size>
void Array<T, size>::Func()
{
	cout << size << endl;
}

int main()
{
	Array<> a;	//完全使用模板缺省参数
	Array<int> b;	//指定一个模板参数类型
	return 0;
}

2. 函数模板

老标准只能为类模板提供默认模板参数,C++11标准可以为函数模板提供默认参数。

class Test
{
public:
	Test() { cout << "构造函数执行" << endl; }
	Test(const Test& test) { cout << "拷贝构造函数执行" << endl; }
	//重载圆括号
	int operator()(int a, int b) const
	{
		return a + b;
	}
};

template<typename T, typename F = Test>
//void TestFunc(const int& a, const int& b, Test func = Test())
void TestFunc(const T& a, const T& b, F func = Test())
{
	cout << func(a, b) << endl;
}

int main()
{
	TestFunc(15, 25);
	return 0;
}

注意:

  1. 同时给模板参数和函数参数提供缺省值。
  2. 注意写法 F func = Test()。
  3. Test重载圆括号。
C++ 中,模板函数指针的结合使用是一种强大且灵活的技术,能够实现泛型编程与运行时多态的结合。模板可以用于抽象函数的型,而函数指针则用于动态绑定函数调用。 ### 函数指针的基本定义 函数指针是指向函数的指针变量,其定义方式如下: ```cpp 返回型 (*指针名)(参数型列表); ``` 例如,一个指向接受两个 `int` 参数并返回 `int` 的函数的指针可以定义为: ```cpp int (*funcPtr)(int, int); ``` ### 模板中使用函数指针模板中使用函数指针可以实现对不同型函数的通用处理。模板可以接受函数指针作为参数,也可以返回函数指针。以下是一个使用模板处理函数指针的示例: ```cpp template <typename Func> auto invokeFunction(Func func, typename Func::argument_type a, typename Func::argument_type b) -> decltype(func(a, b)) { return func(a, b); } ``` 上述代码中,`Func` 是一个模板参数,表示一个函数指针型。`invokeFunction` 函数模板接受一个函数指针 `func` 两个参数 `a` 与 `b`,并调用该函数。 ### 使用 `std::function` `std::bind` 进行封装 C++11 引入了 `std::function`,它可以封装任意型的可调用对象,包括函数指针、lambda 表达式、绑定表达式等。`std::function` 与模板结合使用时,可以实现更灵活的函数对象封装。 ```cpp #include <functional> template <typename T> T applyFunction(std::function<T(T, T)> func, T a, T b) { return func(a, b); } ``` 在上述代码中,`applyFunction` 接受一个 `std::function` 对象,该对象可以是任何符合 `T(T, T)` 签名的函数或可调用对象。 ### 示例代码 以下是一个完整的示例,演示如何在 C++ 中使用模板函数指针: ```cpp #include <iostream> #include <functional> // 定义两个简单的函数 int add(int a, int b) { return a + b; } int multiply(int a, int b) { return a * b; } // 使用模板处理函数指针 template <typename Func> int compute(Func func, int x, int y) { return func(x, y); } int main() { // 使用函数指针作为参数 int result1 = compute(add, 3, 4); std::cout << "Add Result: " << result1 << std::endl; // 使用 std::function 封装函数指针 std::function<int(int, int)> func = multiply; int result2 = compute(func, 5, 6); std::cout << "Multiply Result: " << result2 << std::endl; return 0; } ``` ### 总结 C++ 中的模板函数指针结合使用可以实现高度通用灵活的代码结构。通过模板参数化函数指针型,可以编写出适用于多种函数型的通用代码。此外,`std::function` 提供了更高级的封装,使函数指针的使用更加便捷安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值