C++模板

分类

C++的模板分为函数模板和类模板。
函数模板:

template<typename T>
T myAdd(T a, T b) {
    return a + b;
}

类模板:

template <typename T>
class A {
    ...
}

注意:结构体做成的模板也是类模板;C++中类和结构体的唯一区别就是默认访问权限是private还是public。

主模板和特化

主模板相当于基类,特化相当于对基类的派生;
特化分为全特化(实例化模板的某个具体类型,比如int,float)和偏特化(实例化模板的一类类型,比如指针T*,const T)。

举例说明,主模板:

template <typename T>
class A {
	... // 默认实现,可以和T无关,一般情况也T无关
}

全特化 —— 针对int类型:

template <>
class A<int> {
	...
}

比如:为bool类型优化打印

#include <iostream>

template<typename T>
struct Printer {
    void print(T value) {
        std::cout << "General: " << value << std::endl;
    }
};

// 全特化:为 bool 类型提供更友好的输出
template<>
struct Printer<bool> {
    void print(bool value) {
        std::cout << "Boolean: " << (value ? "true" : "false") << std::endl;
    }
};

int main() {
    Printer<int> p1;
    p1.print(42);        // 输出: General: 42

    Printer<bool> p2;
    p2.print(true);      // 输出: Boolean: true
}

偏特化 —— 针对指针:

template <typename T>
class A<T*> {
	...
}

比如:

#include <iostream>

// 主模板:默认不是指针
template<typename T>
struct is_pointer {
    static constexpr bool value = false;
};

// 偏特化:当 T 是某种类型的指针时
template<typename T>
struct is_pointer<T*> {
    static constexpr bool value = true;
};

int main() {
    std::cout << is_pointer<int>::value << std::endl;      // 0 (false)
    std::cout << is_pointer<int*>::value << std::endl;     // 1 (true)
    std::cout << is_pointer<double*>::value << std::endl;  // 1 (true)
}

有几点需要注意:

  • template<>为主模板全特化的标志,而class A<T*>为主模板偏特化标志;它们格式固定,不会在普通模板中出现
  • 调用的时候,如果没有匹配到任何类型,就会使用主模板的默认定义 —— 这点和基类派生类一致
  • 全特化指的是特定的一个类型,比如int,float;偏特化反而指的是一类类型,比如指针,const;不要理解错了

适用场景

普通模板要处理的场景为:只有类型不同,实现完全相同的场景;
主模板和全特化要处理的场景是:不同类型的内部实现均不相同,具体到单个类型;
主模板和偏特化要处理的场景是:不同类型的内部实现均不相同,具体到一类类型。

posted @ 2025-10-20 11:17  moonのsun  阅读(6)  评论(0)    收藏  举报