自学内容网 自学内容网

C++(10) 模板函数

模版函数

1.1 目前函数的问题
#include <iostream>

using namespace std;

/*
以下函数存在的问题
    1. 功能一致,但是函数参数类型不同
    2. 按照目前的技术手段,只能分别实现不同的函数完成代码
    3. 导致代码冗余、函数冗余、编译冗余

解决方案:
    利用 C++ 模版解决
*/
void printValue(int num);
void printValue(double num);
void printValue(char ch);
void printValue(bool ret);
void printValue(string s);

int main(int argc, char const *argv[])
{
    printValue(10);
    printValue(3.14);
    printValue('G');
    printValue(false);
    printValue("零零零零");

    return 0;
}

void printValue(int num) { cout << num << endl; }
void printValue(double num) { cout << num << endl; }
void printValue(char ch) { cout << ch << endl; }
void printValue(bool ret) { cout << ret << endl; }
void printValue(string s) { cout << s << endl; }
1.2 模版函数案例
#include <iostream> 
#include <deque>

using namespace std;

/*
template 单词汉语对应就是模版
在这里自定义模版,设置模版数据类型为 T 类型

T 是一个数据类型占位符!且不具备实际含义
【模版函数】函数使用模版 T,需要再调用函数时明确 T 对应的具体函数数据类型
*/
template <typename T>
void printValue(T t);

int main(int argc, char const *argv[])
{
    /*
    void printValue<int>(int t)
        实际参数时 int 类型,当前模版 T 对应的具体数据类型为
        int 类型,编译器在编译过程中,动态的对当前模版函数进行了
        修改操作来满足当前函数做需要。
    */
    printValue(100);
    // void printValue<double>(double t)
    printValue(3.14);
    // void printValue<float>(float t)
    printValue(6.18F); // 自动变成 float 类型
    // void printValue<char>(char t)
    printValue('G');
    // void printValue<bool>(bool t)
    printValue(true);
    // void printValue<const char *>(const char *t)
    printValue("零零零零");

    return 0;
}

template <typename T>
void printValue(T t)
{
    cout << "Value : " << t << endl;
}
1.3 模版函数细节
#include <iostream>

using namespace std;

template <typename T>
void test(T t);

/*
模版声明没有任何的冲突问题,尤其是模版函数,相互独立
*/
template <typename T>
void test(T t1, T t2);

/*
当需要调用两个参数类型不同时,可以采用两个模版函数调用
*/
template <typename T, typename Y>
void test2(T s1, Y s2);

void test(int n);

int main(int argc, char const *argv[])
{
    /*
    当前代码中,针对于 test 函数没有具体参数数据类型为 double 情况
    编译器会选择模版函数为当前执行的目标,并且在当前函数调用的过程中
    明确模版对应的具体数据类型为 【double】 类型
    */
    test(20.5F);

    /*
    test 函数存在重载情况,分别是对应模版函数和 int 具体数据类型函数
    编译器会优先选择具体数据类型明确的函数,调用实现
    【先实后虚】
    */
    test(20);

    /*
    template <typename T>
    void test(T t1, T t2)
        语法错误!!!因为当前函数有且只声明了一个模版 T,
        要求在函数的执行过程中,T 类型唯一且统一
    test(10, 3,14); (int, double) 语法错误!
    */
    test(10, 20);
    // test(10, 'A'); 语法错误!请遵守【数据类型一致化原则】
    test('A', 'B');

    test2(10, 'A');
    
    return 0;
}

template <typename T>
void test(T t)
{
    cout << "模版函数触发 value : " << t << endl;
}

void test(int n)
{
    cout << "具体参数为 int 类型函数触发 value : " << n << endl;
}

template <typename T>
void test(T t1, T t2)
{
    cout << "Value 1 : " << t1 << ", Value 2 : " << t2 << endl;
}

template <typename T, typename Y>
void test2(T s1, Y s2)
{
    cout << "Value 1 : " << s1 << ", Value 2 : " << s2 << endl;
}
#include <iostream>

using namespace std;

class Person
{
public:
    Person() {}
    Person(int id, string name, int age) : id(id), name(name), age(age) {}
    Person(const Person &p) : id(p.id), name(p.name), age(age) {}
    ~Person() {}
    
    friend ostream &operator<<(ostream &o, Person *p);
    
    int id;
    string name;
    int age;
};

ostream &operator<<(ostream &o, Person *p)
{
    o << "ID : " << p->id << ", Name : " << p->name
    << ", Age : " << p->age;
    return o;
}

/*
函数中第一个参数 T1 t1 对应的是当前模版声明中的 T1
函数中第一个参数 T1 t2 对应的是当前模版声明中的 T2

都需要具体的实际参数类型来约束模版对应的具体数据类型
*/
template <typename T1, typename T2>
void test(T1 t1, T2 t2)
{
    cout << "T1 : " << t1 
        << " T2 : " << t2 << endl; 
}

template <typename T>
void mySwap(T &t1, T &t2)
{
    T temp = t1;
    t1 = t2;
    t2 = temp;
}

/*
template<> 告知编译器,当前函数需要使用模版函数形式
没有明确的模版类型声明

函数名之后加入的中括号和具体数据类型
    mySwap<Person> 明确告知编译器,
    当前模版对应的具体数据类型为 Person 类型

按照函数声明
    template <typename T>
    void mySwap(T &t1, T &t2);

    T类型对应的具体数据类型在当前实现函数中为 Person 类型

定制化完成 Person 类型的 Swap 交换操作
*/
template <>
void mySwap<Person>(Person &t1, Person &t2)
{
    int id = t1.id;
    string name = t1.name;
    int age = t1.age;

    t1.id = t2.id;
    t1.name = t2.name;
    t1.age = t2.age;

    t2.id = id;
    t2.name = name;
    t2.age = age;
}
int main(int argc, char const *argv[])
{
    // 模版对应的类型需要根据实际情况下来进行判断
    /*
    void test<int, int>(int t1, int t2)
    */
    test(10, 20);
    /*
    void test<int, char>(int t1, int t2)
    */
    test(10, 'A');

    int n1 = 10;
    int n2 = 20;

    mySwap(n1, n2);
    cout << "n1 : " << n1 << " n2 : " << n2 << endl;

    double d1 = 3.14;
    double d2 = 6.18;

    mySwap(d1, d2);
    cout << "d1 : " << d1 << " d2 : " << d2 << endl;

    cout << "-------------------------------" << endl;

    Person *p1 = new Person(1, "张三", 3);
    Person *p2 = new Person(2, "李四", 5);

    cout << p1 << endl;
    cout << p2 << endl;
    cout << "-------------------------------" << endl;
    mySwap(*p1, *p2);
    cout << p1 << endl;
    cout << p2 << endl;

    return 0;
}

    Person *p1 = new Person(1, "张三", 3);
    Person *p2 = new Person(2, "李四", 5);

    cout << p1 << endl;
    cout << p2 << endl;
    cout << "-------------------------------" << endl;
    mySwap(*p1, *p2);
    cout << p1 << endl;
    cout << p2 << endl;

    return 0;
}

原文地址:https://blog.csdn.net/m0_67423245/article/details/135993853

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!