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

2014-11-24 01:21:31 · 作者: · 浏览: 8
st &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);
}

}有如下调用:[cpp] view plaincopyprint int main()
{
std::cout << "::max(7, 42, 68) = " << ::max(7, 42, 68) << std::endl;
std::cout << "::max(7.0, 42.0) = " << ::max(7.0, 42.0) << std::endl;
std::cout << "::max('a', 'b') = " << ::max('a', 'b') << std::endl;
std::cout << "::max(7, 42) = " << ::max(7, 42) << std::endl;
std::cout << "::max<>(7, 42) = " << ::max<>(7, 42) << std::endl;
std::cout << "::max(7, 42) = " << ::max(7, 42) << std::endl;
std::cout << "::max('a', 42.7) = " << ::max('a', 42.7) << std::endl;
return 0;
}

int main()
{
std::cout << "::max(7, 42, 68) = " << ::max(7, 42, 68) << std::endl;
std::cout << "::max(7.0, 42.0) = " << ::max(7.0, 42.0) << std::endl;
std::cout << "::max('a', 'b') = " << ::max('a', 'b') << std::endl;
std::cout << "::max(7, 42) = " << ::max(7, 42) << std::endl;
std::cout << "::max<>(7, 42) = " << ::max<>(7, 42) << std::endl;
std::cout << "::max(7, 42) = " << ::max(7, 42) << std::endl;
std::cout << "::max('a', 42.7) = " << ::max('a', 42.7) << std::endl;
return 0;
}则输出结果为

[cpp]
::max(7, 42, 68)

::max(7, 42, 68)调用了3个参数的模板函数max(),根据这个max()的实现,3个参数都是int类型的,所以调用了非模板函数max()。
[cpp]
::max(7.0, 42.0)

::max(7.0, 42.0)由于两个参数是double的,所以调用了二个参数的模板函数max()。
[cpp]
::max(7.0, 42.0)

::max(7.0, 42.0)同理调用了模板函数。
[cpp]
::max(7, 42)

::max(7, 42) 对于非模板函数和同名的函数模板,如果其他条件都是相同的话,那么在调用的时候,重载解析过程通常会调用非模板函数,而不会从该模板产生出一个实例。
此时调用了非模板函数。
[cpp]
::max(7, 42)

::max(7, 42) 显式的调用了函数模板。
[cpp]
::max(7, 42)

::max(7, 42) 显示的调用了函数模板。
[cpp]
::max('a', 42.7)

::max('a', 42.7)由于模板是不允许自动类型转换的,但是普通函数可以,所以调用了非模板函数。将'a'和42.7转换为int
下面这个例子将会为指针和普通的C字符串重载这个球最大值的模板
[cpp]
namespace
{

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)
{
return ::max(::max(a, b), c);
}

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;
}

inline char const *const &max(char const * const &a, char const *const &b)
{
printf("inline char const *const &max(char const * const &a, char const *const &b)\n");
return std::strcmp(a, b) > 0 a : b;
}

}

namespace
{

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)
{
return ::max(::max(a, b), c);
}

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;
}

inline char const *const &max(char const * const &a, char const *const &b)
{
printf("inline char const *const &max(char const * const &a, char const *const &b)\n");
return std::strcmp(a, b) > 0 a : b;
}

}有如下调用:
[cpp]
int main(int argc, char **argv)
{
int a = 7;
int b = 42;
std::cout << ::max(a, b) << std::endl; // 求两个int的最大值

std::string s = "hey";
std::string t = "you";
std::cout << ::max(s, t) << std::endl; // 求两个std::string类型的最大值

int *p1 = &b;
int *p2 = &a;
std::cout << ::max(p1, p2) << std::endl; // 求两个指针所指向值的最大值

char const *s1 = "David";
char const *s2 = "Nico";
std::cout << ::max(s1, s2) << std::endl; // 求两个c字符串的最大值
return 0;
}

int main(int argc, char **argv)
{
int a = 7;
int b = 42;
std::cout << ::max(a, b) << std::endl; // 求两个int的最大值

std::string s = "hey";
std::string t = "you";
std::cout << ::max(s, t) << std::endl; // 求两个std::string类型的最大值

int *p1 = &b;
int *p2 = &a;
std::cout << ::max(p1, p2) << std::endl; // 求两个指针所指向值的最大值

char const *s1 = "David";
char const *s2 = "Nico";
std::cout << ::max(s1, s2) << std::endl; // 求两个c字符串的最大值
return 0;
}输出结果如下:


当调用重载函数的时候, 调用结果就有可能与该重载函数在此时可见与否这个实例有关,但也有可能没有关系。
事实上,定义一个具有3个参数的max()版本,而且直到该定义处还没有看到一个具有两个int参数的重载max()版本的声明,
那么这个具有3个int实例的max()调用将会使用具有2个参数的模板,而不会使用基于int的重载版本max()。


总结:
1. 模板函数为不同的模板实参定义了一个函数家族。
2. 当你传递模板实参的时候,可以根据实参的类型来对函数模板进行实例化。
3. 你可以显示指定模板参数。
4. 你可以重载函数模板。
5. 当重载函数模板的时候, 把你的改变限制在:显示的指定模板参数。
6. 一定要让函数模板的所有重载版本的声明都位于他们被调用的位置之前。