菜鸟教程 -- 学的不仅是技术,更是梦想!

C++ 教程
C++ 教程 C++ 简介 C++ 环境设置 C++ 基本语法 C++ 注释 C++ 数据类型 C++ 变量类型 C++ 变量作用域 C++ 常量 C++ 修饰符类型 C++ 存储类 C++ 运算符 C++ 循环 C++ 判断 C++ 函数 C++ 数字 C++ 数组 C++ 字符串 C++ 指针 C++ 引用 C++ 日期 & 时间 C++ 基本的输入输出 C++ 结构体(struct) C++ vector 容器 C++ 数据结构

C++ 面向对象

C++ 类 & 对象 C++ 继承 C++ 重载运算符和重载函数 C++ 多态 C++ 数据抽象 C++ 数据封装 C++ 接口(抽象类)

C++ 高级教程

C++ 文件和流 C++ 异常处理 C++ 动态内存 C++ 命名空间 C++ 模板 C++ 预处理器 C++ 信号处理 C++ 多线程 C++ Web 编程

C++ 资源库

C++ STL 教程 C++ 导入标准库 C++ 标准库 C++ 有用的资源 C++ 实例 C++ 测验 C++ <iostream> C++ <fstream> C++ <sstream> C++ <iomanip> C++ <array> C++ <vector> C++ <list> C++ <forward_list> C++ <deque> C++ <stack> C++ <queue> C++ <priority_queue> C++ <set> C++ <unordered_set> C++ <map> C++ <unordered_map> C++ <bitset> C++ <algorithm> C++ <iterator> C++ <functional> C++ <numeric> C++ <complex> C++ <valarray> C++ <cmath> C++ <string> C++ <regex> C++ <ctime> C++ <chrono> C++ <thread> C++ <mutex> C++ <condition_variable> C++ <future> C++ <atomic> C++ <type_traits> C++ <typeinfo> C++ <exception> C++ <stdexcept> C++ <cstdio> C++ <cstdint> C++ <memory> C++ <new> C++ <utility> C++ <random> C++ <locale> C++ <codecvt> C++ <cassert> C++ <cwchar> C++ <climits> C++ <cfloat> C++ <cstdlib> C++ <numbers> C++ OpenCV
(追記) (追記ここまで)

C++ 模板

模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。

模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。

每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector <int>vector <string>

您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。

函数模板

模板函数定义的一般形式如下所示:

template <typenametype> ret-typefunc-name(parameterlist){// 函数的主体}

在这里,type 是函数所使用的数据类型的占位符名称。这个名称可以在函数定义中使用。

下面是函数模板的实例,返回两个数中的最大值:

实例

#include<iostream>#include<string>usingnamespacestd; template <typenameT> inlineTconst& Max(Tconst& a, Tconst& b){returna < b ? b:a; }intmain(){inti = 39; intj = 20; cout << "Max(i, j): " << Max(i, j) << endl; doublef1 = 13.5; doublef2 = 20.7; cout << "Max(f1, f2): " << Max(f1, f2) << endl; strings1 = "Hello"; strings2 = "World"; cout << "Max(s1, s2): " << Max(s1, s2) << endl; return0; }

当上面的代码被编译和执行时,它会产生下列结果:

Max(i, j): 39
Max(f1, f2): 20.7
Max(s1, s2): World

类模板

正如我们定义函数模板一样,我们也可以定义类模板。泛型类声明的一般形式如下所示:

template <class type> class class-name {
.
.
.
}

在这里,type 是占位符类型名称,可以在类被实例化的时候进行指定。您可以使用一个逗号分隔的列表来定义多个泛型数据类型。

下面的实例定义了类 Stack<>,并实现了泛型方法来对元素进行入栈出栈操作:

实例

#include<iostream>#include<vector>#include<cstdlib>#include<string>#include<stdexcept>usingnamespacestd; template <classT> classStack{private: vector<T> elems; // 元素 public: voidpush(Tconst&); // 入栈voidpop(); // 出栈Ttop()const; // 返回栈顶元素boolempty()const{// 如果为空则返回真。returnelems.empty(); }}; template <classT> voidStack<T>::push(Tconst& elem){// 追加传入元素的副本elems.push_back(elem); }template <classT> voidStack<T>::pop(){if(elems.empty()){throwout_of_range("Stack<>::pop(): empty stack"); }// 删除最后一个元素elems.pop_back(); }template <classT> TStack<T>::top()const{if(elems.empty()){throwout_of_range("Stack<>::top(): empty stack"); }// 返回最后一个元素的副本 returnelems.back(); }intmain(){try{Stack<int> intStack; // int 类型的栈 Stack<string> stringStack; // string 类型的栈 // 操作 int 类型的栈 intStack.push(7); cout << intStack.top() <<endl; // 操作 string 类型的栈 stringStack.push("hello"); cout << stringStack.top() << std::endl; stringStack.pop(); stringStack.pop(); }catch(exceptionconst& ex){cerr << "Exception: " << ex.what() <<endl; return -1; }}

当上面的代码被编译和执行时,它会产生下列结果:

7
hello
Exception: Stack<>::pop(): empty stack
AI 思考中...

5 篇笔记 写笔记

  1. #0

    gt

    gt@***ms.org

    52

    第一个例子中typename改为class也是可以的:

    #include <iostream>
    #include <string>
    using namespace std;
    template <class T>
    inline T const& Max (T const& a, T const& b) 
    { 
     return a < b ? b:a; 
    } 
    int main ()
    {
     
     int i = 39;
     int j = 20;
     cout << "Max(i, j): " << Max(i, j) << endl; 
     double f1 = 13.5; 
     double f2 = 20.7; 
     cout << "Max(f1, f2): " << Max(f1, f2) << endl; 
     string s1 = "Hello"; 
     string s2 = "World"; 
     cout << "Max(s1, s2): " << Max(s1, s2) << endl; 
     return 0;
    }
    

    gt

    gt@***ms.org

    9年前 (2017年05月02日)
  2. #0

    gt

    gt@***ms.org

    186

    C++ 中 typename 和 class 的区别

    在 C++ Template 中很多地方都用到了 typename 与 class 这两个关键字,而且好像可以替换,是不是这两个关键字完全一样呢?

    相信学习 C++ 的人对 class 这个关键字都非常明白,class 用于定义类,在模板引入 c++ 后,最初定义模板的方法为:

    template<class T>......

    这里 class 关键字表明T是一个类型,后来为了避免 class 在这两个地方的使用可能给人带来混淆,所以引入了 typename 这个关键字,它的作用同 class 一样表明后面的符号为一个类型,这样在定义模板的时候就可以使用下面的方式了:

    template<typename
    T>......

    在模板定义语法中关键字 class 与 typename 的作用完全一样。

    typename 难道仅仅在模板定义中起作用吗?其实不是这样,typename 另外一个作用为:使用嵌套依赖类型(nested depended name),如下所示:

    class MyArray 
    { 
     public:
     typedef int LengthType;
    .....
    }
    template<class T>
    void MyMethod( T myarr ) 
    { 
     typedef typename T::LengthType LengthType; 
     LengthType length = myarr.GetLength; 
    }
    

    这个时候 typename 的作用就是告诉 c++ 编译器,typename 后面的字符串为一个类型名称,而不是成员函数或者成员变量,这个时候如果前面没有 typename,编译器没有任何办法知道 T::LengthType 是一个类型还是一个成员名称(静态数据成员或者静态函数),所以编译不能够通过。

    gt

    gt

    gt@***ms.org

    9年前 (2017年06月06日)
  3. #0

    oin625

    178***[email protected]

    78

    函数模板可以重载,只要它们的形参表不同即可。例如,下面两个模板可以同时存在:

    template<class T1, class T2>
    void print(T1 arg1, T2 arg2)
    {
     cout<<arg1<<" "<<arg2<<endl; 
    }
    template<class T>
    void print(T arg1, T arg2)
    {
     cout<< arg1<< " "<< arg2<< endl;
    }

    oin625

    178***[email protected]

    8年前 (2018年06月07日)
  4. #0

    Asuka

    pau***[email protected]

    65

    如果需要代码分离,即 template class 的声明、定义,以及 main 函数分属不同文件。例如:

    src_dir
    |____MyStack.h
    |____MyStack.cpp
    |____main.cpp

    则 main.cpp 文件中需要同时包含 .h 文件和 .cpp 文件,不然会出现链接错误。

    // main.cpp
    #include "MyStack.h"
    #include "MyStack.cpp"
    // 其他include
    // main函数主体 

    Asuka

    pau***[email protected]

    6年前 (2020年02月17日)
  5. #0

    起风吧

    104***[email protected]

    186

    其实举个简单的例子反而更利于新手理解本质。

    函数模板:

    #include <iostream>
    using namespace std;
    template <typename T1>
    void Swap(T1& a, T1& b)
    {
     T1 t = a;
     a = b;
     b = t;
    }
    int main()
    {
     int a = 2;
     int b = 3;
     cout <<"a = " << a << "; b = " << b <<endl;
     Swap(a,b);
     cout <<"a = " << a << "; b = " << b <<endl;
     float c = 0.02;
     float d = 0.03;
     cout <<"c = " << c << "; d = " << d <<endl;
     Swap(c,d);
     cout <<"c = " << c << "; d = " << d <<endl;
     return 0;
    }

    类模板:

    #include <iostream>
    using namespace std;
    template <typename T>
    class Op{
    public:
     T peocess(T v)
     {
     return v * v;
     }
    };
    int main()
    {
     Op<int> opInt;
     Op<double> opDouble;
     cout << "5 * 5 = " << opInt.peocess(5) <<endl;
     cout << "0.5 * 0.5 = " << opDouble.peocess(0.5) <<endl;
    }

    起风吧

    104***[email protected]

    5年前 (2021年06月07日)

点我分享笔记

  • 昵称 (必填)
  • 邮箱 (必填)
  • 引用地址

AltStyle によって変換されたページ (->オリジナル) /