C ++の学習(15) - 関数テンプレート

  • 呼ばれるアイデアをプログラミングする別のC ++ の一般的なプログラミング技術は、主な利点は、テンプレートです
  • C ++テンプレートは二つのメカニズムを提供:関数テンプレートおよびクラステンプレートを

1.関数テンプレートの構文

関数テンプレートの効果:

共通機能、および戻り値型パラメータ・タイプの機能を確立するために特異的にカスタマイズされなくてもよい仮想タイプ表現します

構文

template<typename T>
函数定义或声明

説明:

テンプレート - テンプレート宣言を作成します。

型名 - シンボルは、データ・タイプであることを示し、後者は、クラスと交換することができます

T - 一般的なデータ型は、名前は通常、大文字、交換することができます

#include<iostream>
using namespace std;

//函数模板

//两个整型交换的函数
void swapInt(int &a,int &b){
    int temp = a;
    a = b;
    b = temp;
}

//两个浮点型交换的函数
void swapDouble(double &a,double &b){
    double temp = a;
    a = b;
    b = temp;
}

//函数模板
template<typename T> //声明一个模板,告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
void mySwap(T &a,T &b){
    T temp = a;
    a = b;
    b = temp;
}

void test01(){
    int a = 10;
    int b = 20;
    swapInt(a,b);
    //两种方式使用函数模板
    //1.自动类型推导
    mySwap(a,b);
    //2.显示指定类型
    mySwap<int>(a,b);
    cout << "a = " << a <<endl;
    cout << "b = " << b <<endl;

    double c = 1.1;
    double d = 2.2;
    swapDouble(c,d);
    cout << "c = " << c <<endl;
    cout << "d = " << d <<endl;
}

int main(){

    test01();
    return 0;
}

要約:

  • キーワードテンプレートを使用して、関数テンプレート
  • 自動型推論、特定のタイプのため:テンプレート関数を使用するには、2つの方法があります。
  • テンプレートの目的は、型パラメータの再利用性を向上させることです

2.ノート関数テンプレート

注意事項:

  • 自動式の導出は、同じデータ型はTを使用することができます派生しなければなりません
  • あなたが使用する前にTテンプレートは、データの種類を決定する必要があります
//错误,推导不出一致的T类型
int a = 10;
char b = 'c';
mySwap(a,b);
template<class T>
void func(){
    cout << "func调用" << endl;
}
void test02(){
    func();  //错误,编译器无法确定模板的T类型
    func<int>();
}

3.関数テンプレートケース

ケース説明:

  • sort関数テンプレートパッケージを使用して、機能が異なるデータ型の配列を注文することができます
  • アルゴリズムの選択ソートを並べ替え、照合を降順
  • それぞれ配列INT char配列を使用して試験しました
#include<iostream>
using namespace std;

//实现通用 对数组进行排序的函数
//规则 从大到小
//算法 选择
//测试 char数组、 int数组

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

//排序算法
template<class T>
void mySort(T arr[], int len){
    for(int i=0;i<len;i++){
        int max = i;//认定最大值的下标
        for(int j=i+1;j<len;j++){
            if(arr[max]<arr[j]){
                max = j;
            }
        }
        if(max!=i){
            //交换
            mySwap(arr[max],arr[i]);
        }
    }
}

//打印函数模板
template<class T>
void myPrint(T arr[], int len){
    for(int i=0;i<len;i++){
        cout<<arr[i]<<" ";
    }
    cout<<endl;
}

//测试char数组
void test01(){
    char charArr[]="badcfe";
    int len = sizeof(charArr) / sizeof(charArr[0]);
    mySort(charArr,len);
    myPrint(charArr,len);
}

//测试int数组
void test02(){
    int intArr[]={7,5,1,3,9,2,4};
    int len = sizeof(intArr) / sizeof(intArr[0]);
    mySort(intArr,len);
    myPrint(intArr,len);
}

int main(){
    test02();
    return 0;
}

4.正常な機能と機能テンプレートとの間の差

通常の関数と関数テンプレートの違い

  • 自動型変換(暗黙の型変換が)とき通常の関数呼び出しを発生することがあります
  • テンプレート関数呼び出しは、自動型推論を使用する場合は、暗黙の型変換は行われません。
  • 指定されたタイプは、表示モードを使用する場合、暗黙的型変換が発生することが
#include<iostream>
using namespace std;

//普通函数与函数模板区别

//普通函数
int myAdd01(int a, int b){
    return a+b;
}

//函数模板
template<class T>
T myAdd02(T a, T b){
    return a+b;
}

void test01(){
    int a = 10;
    int b = 20;
    char c = 'c';
    cout << myAdd01(a,c) << endl;
    cout << myAdd02<int>(a,c) << endl;
}

int main(){
    test01();
    return 0;
}

概要:彼らが自分のジェネリック型Tを決定することができるので、関数テンプレートを呼び出し、表示モードの指定された型を使用することをお勧めします

5.通常の関数や機能、テンプレートのルールを呼び出し

次のように呼び出し規則は、次のとおりです。

  1. 関数テンプレートと共通の機能を実現することができる場合は、優先呼通常の関数
  2. あなたは空のテンプレートテンプレートパラメータリストで関数を呼び出すことを余儀なくされます
  3. オーバーロード関数テンプレートにも発生する可能性があります
  4. 関数テンプレートは、より良い一致を生成することができた場合は、優先呼関数テンプレート
#include<iostream>
using namespace std;

//普通函数与函数模板调用规则

//普通函数
void myPrint(int a, int b){
    cout << "1" << endl;
}

//函数模板
template<class T>
void myPrint(T a, T b){
    cout << "2" << endl;
}

template<class T>
void myPrint(T a, T b, T c){
    cout << "3" << endl;
}

void test01(){
    int a = 10;
    int b = 20;
    char c = 'c';
    char d = 'd';

    myPrint(a,b);
    myPrint<>(a,b);
    myPrint(a,c);
    myPrint(c,d);
    myPrint(a,b,100);
}

int main(){
    test01();
    return 0;
}

要約:関数テンプレートを提供するので、より良い一般的な機能、あいまいさや、伏せを提供していません

6.制限事項テンプレート

制限事項

  • ユニバーサルテンプレートは万能薬ではありません

例えば:

template<class T>
void f(T a, T b){
    a = b;
}

aとbがアレイに渡された場合、上記のコードに設けられた割り当ては、達成することができません

別の例:

template<class T>
void f(T a, T b){
    if(a>=b){...}
}

上記のコードでは、入ってくるTのデータ・タイプは、人定義のデータ型に似て動作していない場合

テンプレートのオーバーロードを提供し、この問題を解決するためのC ++のように、これらのためにできる特定の種類の提供の具体的なテンプレートを

#include<iostream>
#include<string>
using namespace std;

//模板的局限性

class Person{
public:
    Person(string name,int age){
        this->m_name = name;
        this->m_age = age;
    }
    string m_name;
    int m_age;
};

//对比两个数据是否相等的函数
template<class T>
bool myCompare(T &a, T &b){
    if(a == b){
        return true;
    }
    return false;
}

//利用具体化Person的版本实现代码,具体化优先调用
template<> bool myCompare(Person &p1, Person &p2){
    if(p1.m_name == p2.m_name &&p1.m_age == p2.m_age){
        return true;
    }
    return false;
}

void test01(){
    int a = 10;
    int b = 20;
    if(myCompare(a,b)){
       cout<<"a==b"<<endl; 
    }else{
        cout<<"a!=b"<<endl;
    }
    
}

void test02(){
    Person p1("Tom", 10);
    Person p2("Tom", 11);
    if(myCompare(p1,p2)){
       cout<<"p1==p2"<<endl; 
    }else{
        cout<<"p1!=p2"<<endl;
    }

}

int main(){
    test02();
    return 0;
}

要約:

  • テンプレートの具体的な使用は、あなたがユニバーサルカスタム型を解決することができます
  • テンプレートテンプレートは作成しないことを学ぶが、STLには、システムによって提供されるテンプレートを使用することができます

おすすめ

転載: www.cnblogs.com/maeryouyou/p/12274934.html