C++primer阅读笔记-模板与泛型编程(重载与模板)

  • 函数模板可以被另一个模板或者一个非模板函数重载,名字相同的函数必须具有不同数量或类型的参数。
  • 设计到函数模板,函数匹配规则满足:
    • 对于一个调用,其候选函数包括所有模板实参推断成功的函数模板实例
    • 候选函数总是可行的,因为模板实参推断会排出任何不可行的模板
    • 可行函数按照类型转换来排序
    • 如果恰有一个函数提供比其他函数都更好的匹配,则选择此函数,如果有多个函数提供同样好的匹配,则:
    • 如果同样好的函数中只有一个非模板函数,则选择此函数
    • 如果没有非模板函数,有多个函数模板,则选择其中一个比其他模板更特例化的模板
    • 否则此调用有歧义

编写重载模板

  • 下面函数可以生成一个对象对应的string表示,该对象是任何具备输出运算符的类型
//打印任何我们不能处理的类型
template<tyename T>string debug_rep(const T &t)
{
    ostringstream ret;
    ret << t;
    return ret.str();//返回ret绑定的string副本
}
  • 下面是打印指针的debug_rep版本
//打印任何我们不能处理的类型
template<tyename T>string debug_rep(const T *t)
{
    ostringstream ret;
    ret << t;
    if(t)
        ret << "pointer:" << p;
    else
        ret << "null pointer";
    return ret.str();//返回ret绑定的string副本
}
string s("hello");
debug_rep(s);//调用第一个版本的debug_rep
  • 只有第一个版本的debug_rep是可行的,第二版本要求一个指针参数
debug_rep(&s);//调用第二版本的debug_rep
  • 第一版本能生成实例,其T的类型是string *,需要进行普通指针到const指针的转换
  • 第二版本T类型为string,此为更精确匹配

多个可行版本

  • 考虑一下代码:
const string *sp = &s;
cout << debug_rep(sp) <<endl;
  • 两个版本都是可行的,都是精确匹配
  • 第一个版本实例为:debug_rep<string&>(const string *&),T被绑定为string*
  • 第二个版本实例为:debug_rep<const string>(const string *),T被绑定为const string
  • 由于第二版本比第一版本更加特例化,固解析为第二版本。

非模板和模板重载

string debug_rep(const string &s)
{
    return'"'+s+'"';
}
  • 考虑下边代码
string s("hello");
debug_rep(s);//调用第三个非模块版本的debug_rep
  • 第一和第三个版本都能提供同样好的匹配
    • 第一版本实例化为debug_rep<string>(const string &),T被绑定到string
  • 存在同样好的模板和非模板函数时,编译器会选择非模板函数,当存在多个同样好的非模板函数时,编译器会选择最特例化的版本,一个非模板函数比模板函数更加特例化

重载与类型转换

考虑下边代码

cout << debug_rep("hello");//调用第二版本
  • 上述三个版本都可行

    • debug_rep(const T&),T为char[6]
    • debug_rep(T*),T为const char*
    • debug_rep(const string&),要求从const char*到string的类型转换
  • 对给定的实参来说,第二个版本需要一次数组到指针的转换,这是精确匹配

  • 非模板版本需要一次用户定义的类ixngzhuanhuan,因此没有精确匹配那么好

缺少生命可能导致程序行为异常

  • 使用一个忘记声明的函数,代码将会编译失败
  • 对于重载函数模板的函数,如果编译器可以从模板实例化出与调用匹配的版本,则缺少的声明就不重要了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>