167讲 模板的概念、基本语法、注意实现数组排序、普通函数与函数模板的区别
内容纲要

167讲 模板的概念、基本语法、注意实现数组排序、普通函数与函数模板的区别

  • 该阶段属于C++ 提高编程。
  • 本阶段主要针对C++ 泛型编程和STL 技术做详细讲解,提高C++更深层次的使用

模板

模板就是简历通用的模具,大大提高复用性

  • 模板不可以直接使用,他只是一个框架
  • 模板的通用并不是万能的

函数模板

  • C++ 另一种编程思想称为 泛型编程 ,主要利用的技术就是模板
  • C++ 提供两种模板机制:函数模板类模板

file

使用方法如下代码。

#include <iostream>
#include "string"

using namespace std;

//函数模板
template<typename T>
void mySwap(T &a,T &b) {
    T temp = a;
    a = b;
    b = temp; 
}

void main() {

    int a = 10;
    int b = 20;
    //函数模板有两种使用方法
    //1.自动类型推导
    //mySwap(b, a);

    //2.显示指定类型
    mySwap<int>(a, b);
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
}

Summary

  • 函数模板利用关键字 template
  • 使用函数模板有两种方式:1、自动类型推导 2、显示指定类型
  • 模板的目的是为了提高复用性,将类型参数化

函数模板注意事项

注意事项:

  • 自动类型推导,必须推导出一致的数据类型 T,才可以使用
  • 模板必须确定 T 的数据类型, 才可以使用。

1,当类型不同时,自动类型推导推不出一致的数据类型T,编译器报错

file

2,当未指定T的类型时,编译器亦会报错。需要在<>中显示写入指定的数据类型。

file

函数模板案例---选择排序。

案例描述:

  • 利用函数模板封装一个排序函数,可以对 不同数据类型数组 进行排序

  • 排序规则从大到小,排序算法为选择排序

  • 分别利用char 数组 和 int数组 进行测试。

代码如下

#include<iostream>
#include"string"
using namespace std;
/*
案例描述:

- 利用函数模板封装一个排序函数,可以对 不同数据类型数组 进行排序

- 排序规则从大到小,排序算法为选择排序
- 分别利用char 数组 和 int数组 进行测试。
*/
template<typename T>
void swap(T &a, T &b) {
    T temprary = a;
    a = b;
    b = temprary;
}

template<class T>
void printArr(T arr[]) {
    for (size_t i = 0; i < 6; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
}

template<typename T>
void selectSort(T arr[],int length) {

    for (size_t i = 0; i < length; i++)
    {
        int max = i;
        for (size_t j = i +1; j < length; j++)
        {
            if (arr[j] > arr[max]) {  //选最大的。
                max = j;
            }
        }
        //swap(arr[i], arr[max]);//交换认定的最大值。
        T fortemp = arr[i];
        arr[i] = arr[max];
        arr[max] = fortemp;
    }
}
void test() {
    char test[] = "abcdef";
    int abc[] = { 1,3,5,2,35,75 };
    int length = sizeof(test)/sizeof(test[0]);  //最好在外面算出它的大小,如果在里面计算的话,通过值拷贝可能会出问题。

    selectSort(test,length);
    printArr(test);
}

void main() {
    test();
}

普通函数和模板函数的区别

普通函数与函数模板的区别:

  • 普通函数调用时可以发生自动类型转换(隐式类型转换)
  • 函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
  • 如果利用显示指定类型的方式,可以发生隐式类型转换(说人话:看下面的 myAdd02<int>(a,c);

file

#include <iostream>
#include "string"
using namespace std;
/*
- 普通函数调用时可以发生自动类型转换(隐式类型转换)
- 函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
- 如果利用显示指定类型的方式,可以发生隐式类型转换(说人话:)
*/

int myAdd01(int a, int b) {
    return a + b;
}
template <typename T>
T myAdd02(T a, T b) {
    return a + b;
}
void test() {
    int  a = 10;
    int b = 20;
    char c = 'c';
    cout << myAdd01(a, c);
    //cout << myAdd02(a, c);//自动类型推导。不会发生隐式类型转换。
    cout << myAdd02<int>(a, c);//显示指定类型,会发生隐式类型转换,char -> int;
}
void main() {
    test();
}

Summary

建议使用显示指定类型的方式。调用函数模板,因为自己可以知道要用什么类型的T !!!

普通函数和函数模板的调用规则

file

  • 通过空模板参数列表,强制调用函数模板

file

总结:既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性。。

模板的局限性

  • 模板的通用性不是万能的,就像之前数组排序中我写得传入类,它就不能进行自定义数据类型的匹配。。在用于数组的匹配时也会出现一些局限性。
  • 处理自定义数据类型用模板来实现目前有 2种 方法:
    1. 重载所需要的运算符(但是很麻烦,每个运算符都重载太麻烦了)
    2. 重载模板 语法: template<> T myCompare(T &p1,T &p2){ }

Summary

  • 利用具体化的模板,可以解决自定义类型的通用化
  • 学习模板并不是为了写模板!!!而是在STL能够运用系统提供的模板。。!!!

TIP: STL ( Standard Template Library ) 标准模板库

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇