• 函数模板重载


    函数模板的重载

    #include <cstring>
    #include <iostream>
    #include <typeinfo>
    using namespace std;
    template<typename T>
    T const& max (T const& x, T const& y) {
        cout << "<1" << typeid (x).name () << '>'
            << flush;
        return x < y ? y : x;
    }
    char const* const& max (char const* const& x,
        char const* const& y) {
        cout << "<2" << typeid (x).name () << '>'
            << flush;
        return strcmp (x, y) < 0 ? y : x;
    }
    /*
    char const* max (char const* x, const char* y) {
        return strcmp (x, y) < 0 ? y : x;
    }
    */
    template<typename T>
    T* const& max (T* const& x, T* const& y) {
        cout << "<3" << typeid (x).name () << '>'
            << flush;
        return *x < *y ? y : x;
    }
    template<typename T>
    T const& max (T const& x, T const& y, T const& z) {
        cout << "<4" << typeid (x).name () << '>'
            << flush;
        return ::max (::max (x, y), z);
    }
    /*
    char const* const& max (char const* const& x,
        char const* const& y) {
        cout << "<2" << typeid (x).name () << '>'
            << flush;
        return strcmp (x, y) < 0 ? y : x;
    }
    */
    int main (void) {
        cout << ::max (123, 456) << endl;
        cout << ::max (1.23, 4.56) << endl;
        cout << ::max<string> ("hello", "world")
            << endl;
        cout << ::max ("hello", "world") << endl;
        int x = 123, y = 456;
        cout << *::max (&x, &y) << endl;
        char const* a = "ABC";
        char const* b = "AB";
        char const* c = "A";
        // 编译器优先选择普通函数
        cout << ::max (a, b) << endl; // 2
        // 除非函数模板能够产生具有更好匹配性的函数
        int d = 100, e = 200;
        cout << ::max (d, e) << endl; // 1
        // 在参数传递过程中如果需要隐式类型转换,编译器
        // 只能选择普通函数
        cout << ::max (a, (char*)b) << endl; // 2
        // 通过模板参数表告知编译器使用函数模板
        // 针对指针的版本显然比任意类型版本更加具体
        cout << ::max<> (b, a) << endl; // 3
        // 显式指定的模板参数必须在所选择的重载版本中与
        // 调用参数的类型保持一致
        cout << ::max<char const*> (b, a) << endl; // 1
        cout << ::max (123, 789, 456) << endl;
        // 在函数模板的实例化函数中,编译器优先选择普通
        // 函数,但是该普通函数必须声明于模板之前
        cout << ::max (a, b, c) << endl;
        char const* const& r = max (a, b, c);
        cout << r << endl; // ABC
        char const* g = "123";
        char const* h = "12";
        char const* i = "1";
        max (g, h, i);
        cout << r << endl; // ABC
        return 0;
    }

    一次编译和二次编译:

      重载选择的时机问题:

      模板在第一次编译时,会生成模板函数的内部表示,二次编译实例化模板,此时生成具体指令,确定重载版本,参数类型T具体类型已经知道。

      但是可供选择的普通函数或者模板函数必须声明于该模板函数之前。因为,单向编译器在二次编译确定选择哪一个,但具体选择范围在一次编译时确定。在一次编译时,编译到该模板时只能看见其前面的重载版本。

  • 相关阅读:
    django框架的models
    图像的特征提取
    laravel框架学习
    机器学习--Classifier comparison
    java中的静态变量---static
    初次编程经历
    TERSUS笔记员工信息513-Tersus表格中勾选框升级处理
    TERSUS笔记员工信息512-Tersus勾选框全选和全不选的三种设定方法(转载+补充)
    TERSUS笔记员工信息511-Mysql查询
    TERSUS笔记员工信息510-css文字超出显示
  • 原文地址:https://www.cnblogs.com/kuikuitage/p/9315749.html
Copyright © 2020-2023  润新知