第57课.深入理解函数模板

1.函数模板深入理解

编译器会对函数模板进行两次编译
 对模板代码本身进行编译
 对参数替换后的代码进行编译

注意事项:
函数模板本身不允许隐式类型转换
自动推导类型时,必须严格匹配(类型必须严格匹配)
显示类型指定时,能够进行隐式类型转换

2.多参数函数模板

函数模板可以定义任意多个不同的类型参数

template <typename T1, typename T2, typename T3>
T1 Add (T2 a, T3 b)
{
    return static_cast<T1>(a + b);
}

int r = Add<int, float, double>(0.5, 0.8);

对于多参数函数模板
a.无法自动推导返回值类型(注:无法确定返回值类型时,需要人工指定)
b.可以用从左向右部分指定类型参数

//T1 = int, T2 = double, T3 = double
int r1 = Add<int>(0.5, 0.5);        // 推荐

//T1 = int, T2 = float, T3 = double
int r2 = Add<int, float>(0.5, 0.5);

//T1 = int, T2 = float, T3 = float
int r3 = Add<int, float, float>(0.5, 0.5);

工程中将返回值参数作为第一类型参数。

eg:

#include <iostream>
#include <string>

using namespace std;

template 
< typename T1, typename T2 >
int Add(T1 a, T2 b)
{
    return static_cast<int>(a + b);
}

int main()
{
    int r1 = Add(0.5, 0.8);

    cout << "r1 = " << r1 << endl;     // r1 = 1
    
    return 0;
}

3.当函数重载遇见函数模板

函数模板可以像普通函数一样被重载
a.c++编译器优先考虑普通函数
b.如果函数模板可以产生一个跟好的匹配,那么选择模板
c.可以通过空模板实参列表限定编译器只匹配函数模板

int r1 = Max(1, 2);
double r2 = Max<>(0.5, 0.8);    // 这里 <> 限定编译器只能匹配函数模板

eg:

#include <iostream>
#include <string>

using namespace std;

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

int Max(int a, int b)               // 与T Max(T a, T b)构成重载
{
    cout << "int Max(int a, int b)" << endl;

    return a > b ? a : b;
}

template < typename T >
T Max(T a, T b, T c)
{
    cout << "T Max(T a, T b, T c)" << endl;

    return Max(Max(a, b), c);
}

int 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(5.0, 6.0, 7.0) << endl;     // 函数模板
    
    cout << Max('a', 100) << endl;          // 普通函数,因为函数模板自动推导时。不能隐式转换
    
    return 0;
}
posted @ 2019-12-09 10:26  人民广场的二道贩子  阅读(190)  评论(0编辑  收藏  举报