精华内容
下载资源
问答
  • 函数模板与函数重载

    2017-06-25 21:30:27
    1、 函数模板可以像普通函数一样被重载 2、 C++编译器优先考虑普通函数 3、 如果函数模板可以产生一个更好的匹配,那么选择模板 4、 可以通过空模板实参列表的语法限定编译器只通过模板匹配 特别需要注意的是: ...
    函数模板遇上函数重载时:
    

    1、 函数模板可以像普通函数一样被重载

    2、 C++编译器优先考虑普通函数

    3、 如果函数模板可以产生一个更好的匹配,那么选择模板

    4、 可以通过空模板实参列表的语法限定编译器只通过模板匹配

    特别需要注意的是:
    函数模板不允许自动类型转化

    普通函数能够进行自动类型转换

    函数模板的深入理解

    ― 编译器并不是把函数模板处理成能够处理任意类型的函数

    ― 编译器从函数模板通过具体类型产生不同的函数

    ― 编译器会对函数模板进行两次编译

    ―在声明的地方对模板代码本身进行编译

    ―在调用的地方对参数替换后的代码进行编译



    /*普通函数*/
    int Max(int a, int b)
    {
    cout<<"int Max(int a, int b)"<<endl;
    return a > b ? a : b;
    }

    /*函数模板遇上函数重载*/
    template<typename T>
    T Max(T a, T b)
    {
    cout<<"T Max(T a, T b)"<<endl;
    return a > b ? a : b;
    }


    void main()
    {
    int a = 1;
    int b = 2;
    cout<<Max(a, b)<<endl; //优先普通函数
    cout<<Max<>(a, b)<<endl; //通过空模板实参列表的语法限定编译器只通过模板匹配
    cout<<Max(3.0, 4.0)<<endl; //函数模板可以产生一个更好的匹配,那么选择模板
    cout<<Max('a', 100)<<endl;// 函数模板不允许自动类型转化,普通函数能够进行自动类型转换
    }

    输出结果:






    展开全文
  • 一、引子 考虑求两数较大值函数max(a,b) 对于a,b的不同类型,都有相同的处理形式: return a &lt; b ? b : a; ...(1)宏替换 #define max(a,b) ((a)&...(3)使用函数模板 二、模板 模板是...

    一、引子

    考虑求两数较大值函数max(a,b)
    对于a,b的不同类型,都有相同的处理形式:

    return a < b ? b : a;

    用已有方法解决:
    (1)宏替换 #define max(a,b) ((a)< (b) ? (b) : (a))

    存在的问题:避开类型检查

    (2)重载

    存在的问题:需要许多重载版本

    (3)使用函数模板


    二、模板

    模板是一种参数化的多态工具
    所谓参数化的多态性,是指将程序所处理 的对象的类型参数化,使一段程序代码可以用于处理多不同类型的对象。
    采用模板编程,可以为各种逻辑功能相同而数据类型不同的程序提供一种代码共享的机制。

    模板包括函数模板(function template)、类模板(class template)。本文主要讨论函数模板


    三、函数模板

    (一)、函数模板的使用

    函数模板的一般说明形式如下: 

    template < 模板形参表>

    返回值类型 函数名(模板函数形参表){

        //函数定义体

    }

    1、函数模板的定义以关键字template开头
    2、template之后<>中是函数模板的参数列表
    3、函数模板的参数是类型参数,其类型为class或typename

    template<class T>

    template<class T1, class T2>

    4、模板形参在模板中作为一种类型使用,可以用于函数的形参、函数返回值和函数的局部变量
    5、每个模板形参要在函数的形参列表中至少出现一次

    6、模板参数名的作用域局限于函数模板的范围内


    (二)、函数模板的使用

    1、函数模板为所有的函数提供唯一的一段函数代码,增强了函数设计的通用性
    2、使用函数模板的方法是先说明函数模板,然后实例化成相应的模板函数进行调用执行

    函数模板不是函数,不能被执行

    置换代码中的类型参数得到模板函数——实例化

    实例化后的模板函数是真正的函数,可以被执行

    3、模板被编译了两次

    实例化之前,先检查模板代码本身,查看语法是否正确;在这里会发现语法错误,如果遗漏分号等。
    实例化期间,检查模板代码,查看是否所有的调用都有效。在这里会发现无效的调用,如该实例化类型不支持某些函数调用或操作符等。

    4、普通函数只需要声明,即可顺利编译,而模板的编译需要查看模板的定义(声明和定义需放在同个.h文件)


    (三)、函数模板特化

    假设现在我们有这样一个模板函数max:

    template <typename T>
    const T& max(const T& a, const T& b)
    {

    return a < b ? b : a;

    }

    然后现在我们要比较两个字符串的大小,如:

    const char* str1 = "aaa";
    const char* str2 = "zzz";

    此时如果按一般的实例化,比较的将是str1 和 str2 的大小,即比较指针数值大小,而不是字符串大小,故我们需要实现一个模板函数的特化,如下:

    template<>
    const char* const& max(const char* const& a, const char* const& b)
    {

    return strcmp(a, b) < 0 ? b : a;

    }


    (四)、重载函数模板,非模板函数重载

    C++语言可以重载一个函数模板
    用户可以用非模板函数重载一个同名的函数模板

    max.h:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    #ifndef _MAX_H_
    #define _MAX_H_

    #include <iostream>
    using namespace std;

    template <typename T>
    const T &max(const T &a, const T &b)
    {
        cout << "template max(const T& a, const T& b)" << endl;
        return a < b ? b : a;
    }

    // 函数模板重载
    template <typename T>
    const T &max(const T &a, const T &b, const T &c)
    {
        cout << "template max(const T& a, const T& b, const T& c)" << endl;
        return ::max(a, b) < c ? c : ::max(a, b);
        // ::max 会调用非模板函数
    }

    // 非模板函数重载
    const int &max(const int &a, const int &b)
    {
        cout << "max(const int& a, const int& b)" << endl;
        return a < b ? b : a;
    }

    // 函数模板特化
    template <>
    const char *const &max(const char *const &a, const char *const &b)
    {
        cout << "template <> max(const char* const&a, const char* const& b)" << endl;
        return strcmp(a, b) < 0 ? b : a;
    }

    // 非模板函数重载
    const char *const &max(const char *const &a, const char *const &b)
    {
        cout << "max(const char* const&a, const char* const& b)" << endl;
        return strcmp(a, b) < 0 ? b : a;
    }

    #endif // _MAX_H_

    main.cpp:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    #include <iostream>
    #include <string>
    using namespace std;

    #include "max.h"

    class Test
    {
    public:

        friend bool operator<(const Test &t1, const Test &t2)
        {
            cout << "operator<(const Test& t1, const Test& t2)" << endl;
            return true;
        }
    };

    int main(void)
    {
        //与 std::max 区别开来
        cout <<::max(5.5, 6.6) << endl;     // 自动推导 max(const double&, const double&);
        cout <<::max('a', 'c') << endl;     // 自动推导 max(const char&, const char&);

        Test t1;
        Test t2;
        ::max(t1, t2); // Test::operator<(const Test& t1, const Test& t2)

        const char *str1 = "aaa";
        const char *str2 = "zzz";
        cout <<::max(str1, str2) << endl; //优先选择非模板函数

        cout <<::max<>(str1, str2) << endl; //指定使用模板,进而找到模板特化
        //  cout<<::max<const char*>(str1, str2); // 显式指定模板特化函数max(const char* const&a, const char* const& b)
        cout <<::max(1, 5, 3) << endl; // 模板匹配,进而自动推导

        cout <<::max('a', 50) << endl; // 'a'即97;选择非模板函数(char可以隐式转换成int)

        cout <<::max(97, 100) << endl;          // 优先选择非模板函数

        cout <<::max<>(97, 100) << endl;        // 指定使用模板,进而自动推导
        //  cout<<::max<>('a', 50)<<endl;       // Error,指定使用模板,但编译器不知道怎样推导
        cout <<::max<int>(97, 100) << endl; // 显式指定模板函数max(const int&, const int&)
        cout <<::max<int>('a', 50) << endl; // 显式指定模板函数max(const int&, const int&)


        return 0;
    }


    函数模板可以通过传递的参数类型自动推导,查看是否有合适的函数实例可用,而类模板则必须显式说明模板的类型参数,这样才能实例化模板类实例。


    四、模板的偏特化

    模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化
    (1) 类模板的偏特化
    例如c++标准库中的类vector的定义
    template <class T, class Allocator>
    class vector { // … // };
    template <class Allocator>
    class vector<bool, Allocator> { //…//};
    这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。


    (2) 函数模板的偏特化
      严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。
      template <class T> void f(T);  (a)
      根据重载规则,对(a)进行重载
      template < class T> void f(T*);  (b)
      如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。C++的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。


    参考:

    C++ primer 第四版
    Effective C++ 3rd
    C++编程规范

    展开全文
  • 重载函数模板5.非模板函数重载 1.模板 考虑求两数较大值函数max(a,b) 对于a,b的不同类型,都有相同的处理形式: return a < b ? b : a; 用已有方法解决: (1)宏替换 #define max(a,b) ((a)< (b) ? (b)...

    1.模板

    • 考虑求两数较大值函数max(a,b)
    • 对于a,b的不同类型,都有相同的处理形式:
    return a < b ? b : a;
    
    • 用已有方法解决:
      (1)宏替换 #define max(a,b) ((a)< (b) ? (b) : (a))
      存在的问题:避开类型检查
      (2)重载
      存在的问题:需要许多重载版本,当新增一个函数类型,需要求2个数的最大值时,需要提供一个新的重载版本,不方便扩展
      (3)使用函数模板:结合了宏替换和重载的优势,重载是函数,会做安全类型检查
      为相同逻辑的代码提供模板,当处理不同数据类型时,可以将数据类型当作是参数来传递,让编译器实例化对应版本的函数来处理(让编译器实例化对应版本的函数来处理可以理解为宏替换的过程)。
      程序员只是维护模板,而不同的版本的函数由编译器来维护

    • 模板是一种参数化的多态工具
      这些函数在编译器就决定,是一种静态的多态,与重载一样。虚函数的多态只有一种就是虚函数的多态。
      eg:vector,auto_ptr都是以类模板的方式提供的。

    • 所谓参数化的多态性,是指将程序所处理的对象的类型参数化,使一段程序代码可以用于处理多不同类型的对象。

    • 采用模板编程,可以为各种逻辑功能相同而数据类型不同的程序提供一种代码共享的机制。

    • 模板的分类
      (1)函数模板(function template)
      (2)类模板(class template)

    2.函数模板

    • 函数模板的一般说明形式如下:
    template < 模板形参表>
    返回值类型 函数名(模板函数形参表)
    {
        //函数定义体
    }
    
    • 函数模板的定义以关键字template开头
    • template之后<>中是函数模板的参数列表
    • 函数模板的参数是类型参数,其类型为class或typename(推荐使用typename)
    template<class T>
    template<class T1, class T2>
    
    模板形参表可以有多个
    
    • 模板形参在模板中作为一种类型使用,可以用于函数的形参、函数返回值和函数的局部变量

    • 每个模板形参要在函数的形参列表中至少出现一次

    • 模板参数名的作用域局限于函数模板的范围内

    • 函数模板的使用
      (1)函数模板为所有的函数提供唯一的一段函数代码,增强了函数设计的通用性
      (2)使用函数模板的方法是先说明函数模板,然后实例化成相应的模板函数进行调用执行
      函数模板不是函数,不能被执行
      置换代码中的类型参数得到模板函数——实例化
      实例化后的模板函数是真正的函数,可以被执行
      实例化的过程是在编译的时候完成的(由编译器完成)
      在这里插入图片描述
      (3)模板被编译了两次
      实例化之前,先检查模板代码本身,查看语法是否正确;在这里会发现语法错误,如果遗漏分号等。
      实例化期间,检查模板代码,查看是否所有的调用都有效。在这里会发现无效的调用,如该实例化类型不支持某些函数调用或操作符等。
      (4)普通函数只需要声明,即可顺利编译,而模板的编译需要查看模板的定义(声明和定义需放在同个.h文件)。因模板在编译的时候,需要自动推导,自动推导的函数还需要校验里面的调用是否合法,若编译时,只能看到声明,不能看到实现,则无法进行实例化(链接会出错,编译没错)。

    • 函数模板可以通过传递的参数类型自动推导,查看是否有合适的函数实例可用,而类模板则必须显式说明模板的类型参数,这样才能实例化模板类实例。

    3.函数模板特化

    • 假设现在我们有这样一个模板函数max:
    template <typename T>
    const T& max(const T& a, const T& b)
    {
    
    return a < b ? b : a;
    
    }
    
    然后现在我们要比较两个字符串的大小,如:
    
    const char* str1 = "aaa";
    const char* str2 = "zzz";
    cout<<::max(str1, str2)<<endl;
    此时如果按一般的实例化,比较的将是str1 和 str2 的大小,即比较指针大小,而不是字符串内容大小,故我们需要实现一个模板函数的特化,
    

    在这里插入图片描述

    • 如下:
    template<>
    const char* const& max(const char* const& a, const char* const& b)
    {
    
    	return strcmp(a, b) < 0 ? b : a;
    
    }
    

    4.重载函数模板

    • C++语言可以重载一个函数模板

    • 用户可以用非模板函数重载一个同名的函数模板

    • eg:
      P68\max.h

    #ifndef _MAX_H_
    #define _MAX_H_
    #include <iostream>
    using namespace std;
    
    //模板的定义通常放在头文件中
    //不要将模板的声明放在头文件中,实现放在cpp文件中,一般不要分开放
    template < typename T>
    const T &max(const T &a, const T &b)
    {
        return a < b ? b : a;
    }
    
    
    // 函数模板重载
    //参数不同,构成重载
    template < typename T>
    const T &max( const T &a,  const T &b,  const T &c)
    {
        return ::max(a, b) < c ? c : ::max(a, b);
         // ::max表示调用的是全局的,而不是标准库的
    }
    
    // 非模板函数重载
    //与模板const T &max(const T &a, const T &b)构成了重载
    const  int &max( const  int &a,  const  int &b)
    {
        cout <<  "non template function" << endl;
        cout<<"BBBBBBBBBBBBBBB"<<endl;
         return a < b ? b : a;
    }
    
    //函数模板特化
    template <>
    const  char * const &max( const  char * const &a,  const  char * const &b)
    {
        //return a < b ? b : a;
        cout<<"AAAAAAAAAAAAA"<<endl;
        return strcmp(a, b) <  0 ? b : a;//比较的是内容,而不是指针本身
    }
    
    /*
    模板特化与模板函数的区别:
    模板特化本质上属于模板函数,非模板函数重载不算是模板函数,他是全局函数
    
    */
    #endif  // _MAX_H_
    

    P68\01.cpp

    #include <iostream>
    #include <string>
    using  namespace std;
    
    #include  "max.h"
    // template < typename T>
    // const T &max(const T &a, const T &b)
    // {
    //     return a < b ? b : a;
    // }
    
    //编译完后,编译器会实例化这样一个模板函数
    //是由编译器推导的,叫deduction
    // const int& max(const int &a, const int &b)
    // {
    //     return a < b ? b : a;
    // }
    
    // class Test
    // {
    
    // };
    
    class Test
    {
    public:
    
        friend  bool  operator<(const Test &t1,  const Test &t2)
        {
            return  true;
        }
    };
    
    int main( void)
    {
        //::max(5.5, 6.6)表示调用的是全局的max函数,而不是std中命名空间的max函数
        cout <<::max( 5. 5,  6. 6) << endl;      // 自动推导 max(const double&, const double&);
        cout <<::max( 'a',  'c') << endl;      // 自动推导 max(const char&, const char&);
    
    
        Test t1;
        Test t2;
        ::max(t1, t2);  // Test::operator<(const Test& t1, const Test& t2)
                        //编译error,因为Test类对象不支持<运算
                        //所以需要重载<运算符
    
        const  char *str1 =  "aaa";
        const  char *str2 =  "zzz";
        cout <<::max(str1, str2) << endl; //优先选择非模板函数,若找不到,才考虑模板函数
    
        out <<::max<>(str1, str2) << endl;  //指定使用模板,进而找到模板特化
    
        cout <<::max( 1,  5,  3) << endl;  // 模板匹配,进而自动推导
    
        cout <<::max( 'a',  100) << endl;  // 'a'即97;选择非模板函数(char可以隐式转换成int)
    
        cout <<::max( 97,  100) << endl;           // 优先选择非模板函数
                                            //并不是调用模板推导出的函数,而是调用的是重载的非模板函数
    
        cout <<::max<>( 97,  100) << endl;         //调用模板推导出的函数
        //<>表示让模板推导
    
        cout <<::max< int>( 97,  100) << endl;  // 显式指定模板函数max(const int&, const int&),不是自动推导,而是指定的
        cout <<::max< int>( 'a',  100) << endl;  // 显式指定模板函数max(const int&, const int&)
        return 0;
    }
    
    
    • 测试:
      在这里插入图片描述
      在这里插入图片描述

    5.非模板函数重载

    展开全文
  • cpp代码-函数模板和函数重载调用规则
  • 一、引子 考虑求两数较大值函数max(a,b) 对于a,b的不同类型,都有相同的处理形式: return a 用已有方法解决: ...(3)使用函数模板 二、模板 模板是一种参数化的多态工具 所谓参数化的多

    一、引子

    考虑求两数较大值函数max(a,b)
    对于a,b的不同类型,都有相同的处理形式:

    return a < b ? b : a;

    用已有方法解决:
    (1)宏替换 #define max(a,b) ((a)< (b) ? (b) : (a))

    存在的问题:避开类型检查

    (2)重载

    存在的问题:需要许多重载版本

    (3)使用函数模板


    二、模板

    模板是一种参数化的多态工具
    所谓参数化的多态性,是指将程序所处理 的对象的类型参数化,使一段程序代码可以用于处理多不同类型的对象。
    采用模板编程,可以为各种逻辑功能相同而数据类型不同的程序提供一种代码共享的机制。

    模板包括函数模板(function template)、类模板(class template)。本文主要讨论函数模板


    三、函数模板

    (一)、函数模板的使用

    函数模板的一般说明形式如下: 

    template < 模板形参表>

    返回值类型 函数名(模板函数形参表){

        //函数定义体

    }

    1、函数模板的定义以关键字template开头
    2、template之后<>中是函数模板的参数列表
    3、函数模板的参数是类型参数,其类型为class或typename

    template<class T>

    template<class T1, class T2>


    4、模板形参在模板中作为一种类型使用,可以用于函数的形参、函数返回值和函数的局部变量
    5、
    每个模板形参要在函数的形参列表中至少出现一次

    6、模板参数名的作用域局限于函数模板的范围内


    (二)、函数模板的使用

    1、函数模板为所有的函数提供唯一的一段函数代码,增强了函数设计的通用性
    2、使用函数模板的方法是先说明函数模板,然后实例化成相应的模板函数进行调用执行

    函数模板不是函数,不能被执行

    置换代码中的类型参数得到模板函数——实例化

    实例化后的模板函数是真正的函数,可以被执行

    3、模板被编译了两次
    实例化之前,先检查模板代码本身,查看语法是否正确;在这里会发现语法错误,如果遗漏分号等。
    实例化期间,检查模板代码,查看是否所有的调用都有效。在这里会发现无效的调用,如该实例化类型不支持某些函数调用或操作符等。

    4、普通函数只需要声明,即可顺利编译,而模板的编译需要查看模板的定义(声明和定义需放在同个.h文件)


    (三)、函数模板特化

    假设现在我们有这样一个模板函数max:

    template <typename T>
    const T& max(const T& a, const T& b)
    {

    return a < b ? b : a;

    }

    然后现在我们要比较两个字符串的大小,如:

    const char* str1 = "aaa";
    const char* str2 = "zzz";

    此时如果按一般的实例化,比较的将是str1 和 str2 的大小,即比较指针数值大小,而不是字符串大小,故我们需要实现一个模板函数的特化,如下:

    template<>
    const char* const& max(const char* const& a, const char* const& b)
    {

    return strcmp(a, b) < 0 ? b : a;

    }


    (四)、重载函数模板,非模板函数重载

    C++语言可以重载一个函数模板
    用户可以用非模板函数重载一个同名的函数模板


    max.h:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #ifndef _MAX_H_
    #define _MAX_H_

    #include <iostream>
    using  namespace std;

    template < typename T>
    const T &max( const T &a,  const T &b)
    {
        cout <<  "template max(const T& a, const T& b)" << endl;
         return a < b ? b : a;
    }

    // 函数模板重载
    template < typename T>
    const T &max( const T &a,  const T &b,  const T &c)
    {
        cout <<  "template max(const T& a, const T& b, const T& c)" << endl;
         return ::max(a, b) < c ? c : ::max(a, b);
         // ::max 会调用非模板函数
    }

    // 非模板函数重载
    const  int &max( const  int &a,  const  int &b)
    {
        cout <<  "max(const int& a, const int& b)" << endl;
         return a < b ? b : a;
    }

    // 函数模板特化
    template <>
    const  char * const &max( const  char * const &a,  const  char * const &b)
    {
        cout <<  "template <> max(const char* const&a, const char* const& b)" << endl;
         return strcmp(a, b) <  0 ? b : a;
    }

    // 非模板函数重载
    const  char * const &max( const  char * const &a,  const  char * const &b)
    {
        cout <<  "max(const char* const&a, const char* const& b)" << endl;
         return strcmp(a, b) <  0 ? b : a;
    }

    #endif  // _MAX_H_


    main.cpp:

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #include <iostream>
    #include <string>
    using  namespace std;

    #include  "max.h"

    class Test
    {
    public:

         friend  bool  operator<( const Test &t1,  const Test &t2)
        {
            cout <<  "operator<(const Test& t1, const Test& t2)" << endl;
             return  true;
        }
    };

    int main( void)
    {
         //与 std::max 区别开来
        cout <<::max( 5. 56. 6) << endl;      // 自动推导 max(const double&, const double&);
        cout <<::max( 'a''c') << endl;      // 自动推导 max(const char&, const char&);

        Test t1;
        Test t2;
        ::max(t1, t2);  // Test::operator<(const Test& t1, const Test& t2)

         const  char *str1 =  "aaa";
         const  char *str2 =  "zzz";
        cout <<::max(str1, str2) << endl;  //优先选择非模板函数

        cout <<::max<>(str1, str2) << endl;  //指定使用模板,进而找到模板特化
         //  cout<<::max<const char*>(str1, str2); // 显式指定模板特化函数max(const char* const&a, const char* const& b)
        cout <<::max( 153) << endl;  // 模板匹配,进而自动推导

        cout <<::max( 'a'50) << endl;  // 'a'即97;选择非模板函数(char可以隐式转换成int)

        cout <<::max( 97100) << endl;           // 优先选择非模板函数

        cout <<::max<>( 97100) << endl;         // 指定使用模板,进而自动推导
         //  cout<<::max<>('a', 50)<<endl;       // Error,指定使用模板,但编译器不知道怎样推导
        cout <<::max< int>( 97100) << endl;  // 显式指定模板函数max(const int&, const int&)
        cout <<::max< int>( 'a'50) << endl;  // 显式指定模板函数max(const int&, const int&)


         return  0;
    }



    函数模板可以通过传递的参数类型自动推导,查看是否有合适的函数实例可用,而类模板则必须显式说明模板的类型参数,这样才能实例化模板类实

    例。


    四、模板的偏特化

    模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化
    (1) 类模板的偏特化
    例如c++标准库中的类vector的定义
    template <class T, class Allocator>
    class vector { // … // };
    template <class Allocator>
    class vector<bool, Allocator> { //…//};
    这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。
    (2) 函数模板的偏特化
      严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。
      template <class T> void f(T);  (a)
      根据重载规则,对(a)进行重载
      template < class T> void f(T*);  (b)
      如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。C++的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。


    参考:

    C++ primer 第四版
    Effective C++ 3rd
    C++编程规范


    展开全文
  • 函数模板跟普通函数一样,也可以重载。 C++编译器优先考虑普通函数 如果函数模板可以产生一个更好的匹配,那么就选择函数模板 // This program uses a function template. #include <iostream> #include &...
  • 函数模板,函数模板重载,可变参数模板,函数模板覆盖,通过引用交换数据.pdf
  • 前面讲到了函数模板,那么函数模板可不可以与普通的函数重载一起存在呢? 下面来试验一下: #include<iostream> using namespace std; //当模板函数遇上函数重载 template<typename T> void ...
  • 函数模板与函数重载的区别

    千次阅读 2020-02-22 22:26:05
    函数模板: 所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需...
  • 所谓的函数模板重载是指,普通函数的版本,函数模板的版本和函数模板特例化的版本可以共存,例如: //普通函数版本 bool Compare(char* a, char* b) { cout << "普通函数版本" << endl; return ...
  • 函数模板模板重载函数模板显示具体化(explicit specialization)
  • 下面我来说说C++里面的函数模板: #include<iostream> using namespace std; int Max(int a, int b) { cout << "int Max(int a, int b)" << endl; return a > b ? a : b; } ...
  • 所谓模板,实际上是建立一个通用函数或类,其类内部的类型和函数的形参类型不具体指定,用一个虚拟的类型来代表。这种通用的方式称为模板模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码...
  • 为满足这种需求,可以重载常规函数定义那样重载模板定义。和常规重载一样,被重载模板函数特征标必须不同。例如,下面的程序新增了一个交换模板,用于交换两个数组中的元素。原来的模板的特征标为(T &, T&),...
  • c++运用模板函数和函数模板实现运算符重载的差异是什么,各自有什么利弊???
  • 函数模板可以像普通函数一样被重载 C++编译器优先考虑普通函数 如果函数模板可以产生一个更好的匹配,那么选择模板 可以通过空模板实参列表的语法限定编译器只通过模板匹配 #include<iostream...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 90,113
精华内容 36,045
关键字:

函数模板是否可以重载