zoukankan      html  css  js  c++  java
  • 函数模板重载

    函数模板的重载

    #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具体类型已经知道。

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

  • 相关阅读:
    js获取input file文件二进制码
    nginx新手入门
    代码神器Atom,最常用的几大插件,你值得拥有。
    css3 3d 与案例分析
    express搭建简易web的服务器
    hosts文件管理和nginx总结
    css3 3D
    问题大神
    面试题整理
    版本控制简介,git使用----使用GitHub托管代码
  • 原文地址:https://www.cnblogs.com/kuikuitage/p/9315749.html
Copyright © 2011-2022 走看看