C++ 仿函数和模板进阶

仿函数介绍

仿函数(Function Object)是行为类似函数的对象。简单说,就是通过重载operator()运算符,让类的实例可以像函数一样被调用。

基本示例

class Adder {
public:
    int operator()(int a, int b) const {
        return a + b;
    }
};

int main() {
    Adder add;          // 创建一个仿函数对象
    int result = add(3, 4); // 像函数一样调用
    // result = 7
}
//////////////////////////////////////////////////
class Less//利用仿函数比较大小
{
public:
	bool operator()(int x,int y)
	{
		return x<y;
	}
};
int main()
{
	Less functor;
	cout<<functor(1,2);
}

为什么需要仿函数?

  1. 可以保存状态:相比普通函数,仿函数可以在多次调用间保持状态

    class Counter {
        int count = 0;
    public:
        int operator()() { return ++count; }
    };
    
  2. 可作为模板参数:STL算法常接受仿函数作为参数

    std::sort(vec.begin(), vec.end(), MyComparator());
    
  3. 类型安全:比函数指针更安全,编译器可以做更多检查

STL中的常见仿函数

#include <functional>

// 算术运算
std::plus<int>()(1,2);      // 3
std::minus<int>()(5,3);     // 2

// 比较运算
std::greater<int>()(5,3);   // true
std::less<int>()(2,3);      // true

// 逻辑运算
std::logical_and<bool>()(true, false); // false

非类型模板参数

非类型模板参数是指用常量作为模板参数,在模板中可当作常量使用。与类型参数不同,非类型参数必须是编译期可确定的整型常量、枚举或指针。

关键点:

  • 语法:template<class T, size_t N = 10>
  • 限制:浮点数、类对象和字符串不能作为非类型参数
  • 应用场景:常用于指定数组大小等编译期确定的常量值

示例:

template<class T, size_t N = 10>
class array {
    T _array[N];  // 使用非类型参数N作为数组大小
    // ...
};

相对#define而言,非类型模板参数可以修改,对比#define更为灵活

模板特化

函数模板特化

当通用模板无法处理某些特殊类型时,可以通过特化提供特殊实现。

特化步骤:

  1. 必须先有基础模板
  2. 使用template<>声明特化
  3. 函数名后指定特化类型
  4. 参数类型必须与基础模板完全一致

示例:

// 基础模板
template<class T>
bool Less(T left, T right) { return left < right; }
// 假设我要比较两个日期的大小,然而传递了日期对象的指针,如果没有进行特化,则会比较地址大小
// 特化版本
template<> 
bool Less<Date*>(Date* left, Date* right) { return *left < *right; }

注意: 函数模板特化不如直接重载函数直观,通常建议直接提供重载函数而非特化。

类模板特化

全特化

将模板所有参数都明确指定:

template<>
class Data<int, char> { /*...*/ };
偏特化

部分特化或对参数添加额外限制:

// 部分特化
template<class T1>
class Data<T1, int> { /*...*/ };

// 指针特化
template<class T1, class T2>
class Data<T1*, T2*> { /*...*/ };

// 引用特化
template<class T1, class T2>
class Data<T1&, T2&> { /*...*/ };

应用场景: 当需要对指针或引用等特殊类型进行不同处理时特别有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值