C++ Templates读书笔记1__函数模板 (一)

2014-11-24 01:21:31 · 作者: · 浏览: 9

模板是泛型编程的基础,所谓泛型编程,就是以独立与任何特定类型的方式编写代码。
函数模板的示例:
[cpp]
template
inline const T &max(const T &a, const T &b)
{
T tmp = (a > b) a : b;
return tmp;
}

template
inline const T &max(const T &a, const T &b)
{
T tmp = (a > b) a : b;
return tmp;
}模板定义以关键字template开始,后接模板形参表, 模板形参表用<>括住一个或者多个模板形参的列表,以逗号分隔。
类型形参跟在关键字class或者typename之后定义。类型参数是T。
以下操作使用了函数模板
[cpp]
int main()
{
printf("ret = %f\n", ::max(11, 22));
return 0;
}

int main()
{
printf("ret = %f\n", ::max(11, 22));
return 0;
}程序根据不同的参数类型,实例化了相应类型的模板实例, 如上面的例子,参数类型为int,则程序就有调用一下代码的语义。

[cpp]
const int &max(const int &a, const int &b)
{
T tmp = (a > b) a: b;
return tmp;
}

const int &max(const int &a, const int &b)
{
T tmp = (a > b) a: b;
return tmp;
}那么如果函数调用的实参使用了两种不同的类型,则会发生错误,如下的调用
[cpp]
::max(1, 1.1); // error 第一个参数类型为int,第二个参数类型为double

::max(1, 1.1); // error 第一个参数类型为int,第二个参数类型为double解决这个错误的办法有以下三种:
1. 对实参进行强制类型转换,使他们可以相互匹配
[cpp] view plaincopyprint ::max(static_cast(1), 1.1);

::max(static_cast(1), 1.1);2. 显示指定T的类型
[cpp]
::max(static_cast(1), 1.1);

::max(static_cast(1), 1.1);3. 指定两个参数可以有不同类型
如以下模板的定义:
[cpp]
template
inline const T2 &add(const T1 &a, const T2 &b)
{
T2 tmp = a + b;
return tmp;
}

template
inline const T2 &add(const T1 &a, const T2 &b)
{
T2 tmp = a + b;
return tmp;
} 如下调用
[html] view plaincopyprint int main()
{
printf("ret = %.2f\n", ::add(1, 1.1));
return 0;
}

int main()
{
printf("ret = %.2f\n", ::add(1, 1.1));
return 0;
}如果模板参数定义如下:
[cpp]
template
inline const T3 &add(const T1 &a, const T2 &b)
{
T3 tmp = a + b;
return tmp;
}

template
inline const T3 &add(const T1 &a, const T2 &b)
{
T3 tmp = a + b;
return tmp;
}如下调用
[cpp]
int main()
{
printf("ret = %.2f\n", ::add(1, 1.1));
return 0;
}

int main()
{
printf("ret = %.2f\n", ::add(1, 1.1));
return 0;
}则编译器会发生错误。编译器没有办法隐式的为T3赋值,这种情况下必须显示的指定T3的类型, 如下调用
[cpp]
int main()
{
printf("ret = %.2f\n", ::add(1, 1.1));
urn 0;
}

int main()
{
printf("ret = %.2f\n", ::add(1, 1.1));
return 0;
}显然这样的调用有些过于复杂,对于T3,可以显示的为其指定类型,而T1, T2则可以根据实参类型进行演绎。
也就是说,改变模板参数的声明顺序,只显示指定第一个实参。
你必须指定“最后一个不能被隐式演绎的模板实参之前的”所有实参类型, 如下的模板定义:
[cpp]

template
inline const RT &add(const T1 &a, const T2 &b)
{
RT tmp = a + b;
return tmp;
}

template
inline const RT &add(const T1 &a, const T2 &b)
{
RT tmp = a + b;
return tmp;
}如下调用

[cpp]
int main()
{
printf("ret = %.2f\n", ::add(1, 1.1));
return 0;
}

int main()
{
printf("ret = %.2f\n", ::add(1, 1.1));
return 0;
}在这个例子中,调用add时显式的将RT指定为double, 但是其他两个参数T1和T2可以根据调用实参分别演绎为int和double.


和普通函数一样,函数模板也可以被重载
一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非函数模板。


如下程序:
[cpp]
namespace
{
inline int const &max(int const &a, int const &b)
{
printf("max(int const &a, int const &b)\n");
return a < b a : b;
}

template
inline T const &max(T const &a, T const &b)
{
printf("template inline T const &max(T const &a, T const &b)\n");
return a < b a : b;
}

template
inline T const &max(T const &a, T const &b, T const &c)
{
printf("template inline T const &max(T const &a, T const &b, T const &c)\n");
return ::max(::max(a, b), c);
}

}

namespace
{
inline int const &max(int const &a, int const &b)
{
printf("max(int const &a, int const &b)\n");
return a < b a : b;
}

template
inline T const &max(T const &a, T const &b)
{
printf("template inline T const &max(T con