C++泛型编程

    在c++中,模板是泛型编程的基础。模板是创建类或函数的蓝图或公式。编译器自
动为我们用实际的类型替代模板中类型参数,编译生成代码.编写模板代码时,对实参
类型的要求尽可能少是很有益的。
    函数模板:
    template <typename T>
    int compare(const T &v1, const T &v2) {
        if (v1 < v2) return -1;
        if (v2 < v1) return 1;
        return 0;
    }
    类模板:
    template <class Type> class QueueItem {
        QueueItem(const Type &t):item(t), next(0) { }
        Type item;
        QueueItem *next;
    }
1.模板形参表:
    基本格式为: template <typename T> 或者 template <class T>.模板形参可以
是表示类型的类型形参,也可以是表示常量表达式的非类型形参,非类型形参跟在类型
说明符之后声明。typename 和 class没有区别,可以互换使用。但关键字typename是
作为标准C++的组成部分加入到C++中的, 因此旧的程序更有可能只用关键字class。
2.inline函数模板
    inline说明符必须放在模板形参之后,函数返回值之前,不能放在关键字template
之前。如:template <typename T> inline T min(const T&, const T&);
3.在模板定义内部指定类型
    除了定义数据成员或函数成员之外,类还可以定义类型成员。例如,标准库的容器
类定义了不同的类型,如size_type,使我们参够以独立于机器的方式使用容器。如果
要在函数模板内部使用这样的类型,必须告诉编译器我们正在使用的名字指的是一个类
型。必须显示地这样做,因为编译器(以及程序的读者)不能通过检查得知,由类型形
参定义的名字何时是一个类型何时是一个值。例如,考虑下面的函数:
template <class Parm, class U>
Parm fcn(Parm* array, U value) {
    Parm:: size_type * p;   //如果Parm::size_type是一个类型,则这是一个声明
                           //如果Parm::size_type是一个对象,则这是相乘。
}
我们知道size_type必定是绑定到Parm的那个类型的成员,但我们不知道size_type是一
个类型成员的名字还是一个数据成员的名字,默认情况下,编译器假定这样的名字指定
数据员,而不是类型。
如果希望编译器将size_type当作类型,则必须通过如下方法显示告诉编译器这样做:
template <class Parm, class U>
Parm fcn(Parm* array, U value) {
    typename Parm::size_type * p; //声明p为一个指针
}
从而必须确保Parm类型必须具有size_type的成员,而且该成员必须是一个类型。
4.非类型模板形参
    模板形参不必都是类型。在调用函数时,非类型形参将用值代替,值的类型在模板
形参表中指定。如:
template <class T, size_t N> void array_init(T (&parm)[N]) {
    for (size_t i = 0; i != N; ++i) {
        parm[i] = 0;
    }
}
int x[42];
double y[10];
array_init(x); //实例化为array_init(int(&)[42])
array_init(y); //实例化为array_init(double(&)[10])
5.模板特化
    我们并不总是能够写出对所有可能被实例化的类型都最合适的模板。某些情况下,
通用模板定义对于某个类型来说,可能完全是错误的,通用模板也许不能编译或者做错
误的事情,另外一些情况下,可以利用关于类型的一些特殊知识,可以编写比从模板实
例化来的函数更有效率的函数。
    考虑如下函数:
template <typename T>
int compare(const T &v1, const T &v2) {
    if (v1 < v2) return -1;
    if (v2 < v1) return 1;
    return 0;
}
如果用两个const char*调用这个模板定义,函数将比较指针值。它将告诉我们这两个
指针在内存中的相对位置大小,但没有说明了与指针所指数组的内容相关的任何事情。
    函数模板特化定义中一个或多个模板形参的实际类型或实际值是指定的。格式如下
    a.关键字template后面接一对空的尖括号(<>);
    b.再接模板名和一对尖括号,尖括号中指定这个特化定义的模板形参;
    c.函数形参表;
    d.函数体。
    下面的程序定义了当模板形参类型绑定到const char*时,compare函数的特化:
template <>
int compare<const char*>(const char* const &v1,
                         const char* const &v2) {
    return strcmp(v1, v2);
}
特化的声明必须与对应的模板相匹配。
6.类模板的特化
    template<> class Queue<const char*> {
        ...
    }
7.类模板的部分特化
    template <class T1, class T2>
     class some_template {
         ...
     }


    template <class T1>
    class some_template<T1, int> {
        ...
    }
<think>我们正在讨论MP4的box结构,但用户突然转向了C++编程。根据对话历史,用户之前询问了MP4 box的详细结构,而现在提供了关于C++编程的引用,并明确表示想了解C++编程的相关知识。因此,我们需要切换话题,忽略之前关于MP4的讨论,专注于回答C++编程。 用户需求:了解C++编程的概念、使用方法、应用场景等。 根据提供的引用,我们可以整理以下要点: 概念: - 编程是一种编程思想,旨在编写不依赖具体数据类型的通用程序(引用[1]、[5])。 - 通过模板技术实现,将算法和数据结构分离(引用[1])。 - STL(标准模板库)是编程的典例子(引用[1]、[4])。 使用方法: - 函数模板:定义一个通用函数,用虚拟类型占位,编译器根据传入的实参类型推演并生成具体函数(引用[2]、[5])。 - 示例:`max`函数模板,可以显式指定类型(如`max<double>(a,b)`)或让编译器自动推导(引用[3])。 - 类模板:用于创建通用类,如STL中的容器(vector, list等)(引用[4])。 应用场景: - STL:提供了算法(algorithm)、容器(container)、迭代器(iterator)等(引用[4])。 - 需要通用算法(如排序、查找)和通用容器(如动态数组、链表)的场景。 我们将按照以下结构组织回答: 1. 概念:解释编程的概念和目的。 2. 核心机制:模板(函数模板和类模板)的工作机制。 3. 使用方法:通过示例展示如何定义和使用函数模板和类模板。 4. STL介绍:简要说明STL的组成和意义。 5. 应用场景:列举典应用场景。 注意:回答中如果涉及引用,在引用内容后自然添加引用标识,如[^1]。 同时,根据系统指令,数学表达式需要用$...$或$$...$$格式,但本回答中可能涉及较少数学内容,主要关注代码示例。 另外,生成相关问题,放在最后。 开始回答: </think>### C++编程详解 #### 1. **核心概念** 编程是一种**数据类型无关**编程范式,核心思想是通过参数化类型实现代码复用。与面向对象的多态不同,在编译期完成类型绑定,不产生运行时开销[^1]。其核心优势在于: - **类型安全**:编译期类型检查 - **代码复用**:同一套逻辑适配不同类型 - **性能优化**:消除运行时类型转换 ```mermaid graph LR A[模板定义] --> B[编译器处理] B --> C[int类型实例] B --> D[double类型实例] ``` #### 2. **实现机制** ##### (1) 函数模板 ```cpp template <typename T> // 类型参数声明 T max(T a, T b) { return (a > b) ? a : b; } // 使用示例 int main() { cout << max(3, 5); // 隐式实例化int版本[^2] cout << max<double>(2.1, 3.8); // 显式指定double版本[^3] } ``` - **编译过程**: 1. 模板解析:建立抽象语法树 2. 实例化:根据调用生成具体函数(如`max<int>`) 3. 代码生成:输出机器指令 ##### (2) 类模板 ```cpp template <class T> class Stack { private: vector<T> elems; public: void push(T const&); T pop(); }; // 使用示例 Stack<string> strStack; // 字符串栈 strStack.push("hello"); Stack<int> intStack; // 整数栈 intStack.push(42); ``` #### 3. **STL标准库应用** STL(Standard Template Library)是编程的典范实现,包含三大核心组件[^4]: | 组件 | 功能 | 示例 | |------------|-----------------------|---------------------| | 容器 | 数据结构封装 | `vector<T>`, `map<K,V>` | | 算法 | 通用操作 | `sort()`, `find()` | | 迭代器 | 容器与算法间的桥梁 | `begin()`, `end()` | ```cpp // STL使用示例 vector<double> nums = {3.14, 2.71, 1.618}; sort(nums.begin(), nums.end()); // 排序算法 ``` #### 4. **关键技术点** - **类型推导**: - 自动推导:`max(3, 5)` → `max<int>` - 需显式指定的场景: ```cpp template <class T> void print(initializer_list<T> vals) {} print<double>({1.1, 2.2}); // 列表初始化需显式声明类型 ``` - **特化与偏特化**: ```cpp template<> // 全特化 class Stack<bool> { /* 位向量实现 */ }; template<class T> // 偏特化 class Stack<T*> { /* 指针类型处理 */ }; ``` #### 5. **应用场景** 1. **通用数据结构**:链表/栈/队列等容器类 2. **数值计算**:矩阵运算库(如$Matrix<int, 3, 3>$) 3. **算法抽象**:排序/查找等通用算法 4. **类型安全接口**:智能指针(`shared_ptr<T>`) > ⚠️ 注意事项:模板错误通常在实例化时暴露,错误信息可能冗长复杂。可使用`static_assert`进行编译期检查: > ```cpp > template<class T> > void process(T val) { > static_assert(is_arithmetic<T>::value, "需数值类型!"); > } > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值