C++----模板进阶

一、模板参数类型

1.作用域问题

template<class Container>
void Print(const Container& v) {
    // 必须使用typename明确告诉编译器这是类型
    typename Container::const_iterator it = v.begin();
    while (it != v.end()) {
        cout << *it << " ";
        ++it;
    }
}
  • typename作用:当模板参数中存在嵌套类型时,必需使用typename明确标识。(原因:因为模板参数里的嵌套体类型未实例化,无法明确类型,加typename来明确类型。)
  • 替代方案:使用auto自动推导(C++11起)
auto it = v.begin(); // 更简洁的写法

      但是在有些场景下是不能用这种简洁的写法,比如在priority_queue的类模板中:

2.非类型模板参数

template<class T, size_t N>
class Stack {
private:
    T _a[N]; // 非类型模板参数必须是常量整型
};
  • 特点:
  1. 必须是常量
  2. 必须是整型(int,size_t等)
  3. 实例化后不可修改

3.按需实例化

Stack<int, 10> st1; // 模板类声明时不会实例化所有成员
st1.func();         // 只有调用时才会实例化对应成员
  • 核心特点:模板类成员函数只有在被调用时才会实例化

二、array容器

array<int, 10> a;
a[10] = 1; // 严格越界检查(编译/运行时报错)
与普通数组对比
特性普通数组array容器
越界读不检查严格检查
越界写部分情况检查严格检查
迭代器支持支持
作为参数传递退化指针保留大小信息

三、模板特化

1.函数模板特化

  • 特点:必须显示指定模板参数类型
template<>
bool Less<int*>(int* left, int* right) {
    return *left < *right;
}

2.类模板特化

  • 特化类型:
    • 全特化:完全指定所有模板参数
    • 偏特化:
    1. 部分参数特化
    2. 对参数类型添加限制(指针、引用等)
// 原模板
template<class T1, class T2>
class Data { /*...*/ };

// 全特化
template<>
class Data<int, double> { /*...*/ };

// 偏特化(部分参数)
template<class T1>
class Data<T1, double> { /*...*/ };

// 偏特化(类型限制)
template<class T1, class T2>
class Data<T1*, T2*> { /*...*/ };

四、模板分离编译

1.典型问题

// Stack.h
template<class T, class Container>
void Stack<T, Container>::push(const T& x) { /*...*/ }
  • 链接错误原因:模板成员函数未被实例化,导致符号表找不到对应实现。

2.解决方案

方案一:显示实例化

template class Stack<int, vector<int>>; // 在.cpp文件中显式实例化

方案二:声明定义统一存放

template class Stack<int, vector<int>>; // 在.cpp文件中显式实例化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值