模板、实参推导与重载
来源:互联网 发布:淘宝买家好评率未知 编辑:程序博客网 时间:2024/06/09 20:20
以下的内容都是在VC++6.0上测试的。
一、如果非引用、非指针形参的差异只是一个const,那不能构成重构,如:
(1) template <typename T>
void func1(T t)
{ ............ }
(2) template <typename T>
void func1(const T t)
{ ............ }
编译时,上面的(1)和(2)会报重复定义的错误:
error C2995: 'func1' : template function has already been defined
如果改成引用或指针再编译就通过了。
二、引用、指针类型形参,重载函数的选择
(3) template <typename T>
void func2(const T &t)
{ ............ }
(4)template <typename T>
void func2(T &t)
{..................}
(5) template <typename T>
void func3(const T *t)
{ ............. }
(6) template <typename T>
void func3(T *t)
{ ............. }
int i = 1; int *pi = &i;
func2(i); func3(pi); 这2个函数调用的都是没有const的函数版本,即(4)和(6)。
const int ci =2;
const int *pci = pi;
int *const cpi = pi;
func2(ci); 编译出错:
error C2667: 'func2' : none of 2 overload have a best conversion
error C2668: 'func2' : ambiguous call to overloaded function
func2(2); 编译出错,错误原因同上
func3(pci); 编译出错,错误原因同上
func3(cpi); 编译正确,调用的是(6)
三、实参推导的类型
double x[20];
func1(x); 推导出来的参数类型是double*,函数内sizeof(T)是4
func2(x); 调用的是(4),推导出来的参数类型是double[20],函数内sizeof(T)是160
func3(x); 调用的是(6),推导出来的参数类型是duble,T*是指向第一个元素的指针
double y[20]; double z[21];
(7) template <typename T>
void func4(T &t1, T &t2)
{.......................}
func4(x, y); 推导出来T是double[20]
func4(x, z); 编译错误, double[20]和double[21]冲突
(8) template <typename T>
void func5(T t)
{ .............. }
(9) template <typename T>
void func5(T &t)
{ ............. }
(10) template <typename T>
void func5(T *t)
{ .................... }
int i=1; int *pi=&i; double x[20];
func5(i); 编译出错,报有2个满足匹配条件的,T是int,应该是(8)、(9)
func5(pi); 编译出错,报有3个满足条件的错误。应该是(8)(9)的T推导成int *,(10)的T推导成int
func5(x); 编译出错,报有3个满足匹配的错误,(8)的T推导成double*,(9)的T推导成double[20],(10)的T推导成double
四、基类、派生类的类型转换
template<typename T>
class B
{ ............ }
template<typename T>
class D:public B<T>
{ ................. }
template<typename T>
void f(B<T> *c)
{ ................. }
template<typename T>
void g(B<T> c)
{ ........................ }
D<long> dl; B<int> bi;
f(&dl);
f(&bi);
g(bi);
g(dl);
这4个调用都可以编译通过并运行。
根据以上的几个实验,得到以下的一些结论:
1. 如果形参的声明是引用时,推导出来的类型是实参的实际类型,如前面的数组,是不会退化为指针的;
2. 如果实参是不带const修饰的,推导时也找不带const的函数版本;
3. 如果实参是带const的,如func2(ci),由于const int来推导(4)中的T,用int来推导(5)中的T,最后得到的都是func2(const T &),所以func2(ci)编译时会报有2个同等匹配的函数的错误。
4.形参可以是实参的基类类型,或者,实参是个指向X类的指针,形参是个指向X基类的指针。
C++Primier里的描述:
一般而言,不会转换实参以匹配已有的实例化,相反,会产生新的实例。
编译器只会执行两种转换:
1. const转换: 接受const引用或const指针的函数可以分别用非const对象的引用或指针来调用,无须产生新的实例化。如果函数接受非引用类型,形参类型和实参类型都忽略const,即无论传递const或非const对象给接受非引用的类型,都使用相同的实例化。
2. 数组或函数到指针的转换: 如果模板形参不是引用类型,则对数组或函数类型的实参应用常规指针转换。数组实参将当作执行其第一个元素的指针,函数实参当作指向函数类型的指针。
- 模板、实参推导与重载
- 模板实参推断与引用
- C++中的重载函数、重载函数匹配与实参转换
- 模板实参推断与函数指针
- 模板实参推断与函数指针
- P4-重载与模板
- 函数重载与模板
- 重载与模板知识点
- 重载与模板
- 重载与模板
- c++重载与模板
- 函数重载与模板
- 模板与泛型编程之模板实参推断
- c++多态中关于参数匹配推导与模板参数推导
- 模板实参推断与函数指针的一些事
- C++语法基础--模板实参推断,模板类型形参的实参的受限转换,模板实参推断与函数指针
- C++模板特化与重载
- 模板的特化与重载
- 面向对象技术的软件设计
- EGL接口介绍
- SHGetFileInfo(获取文件信息)
- Linux命令整理
- 雾
- 模板、实参推导与重载
- 田忌赛马(Tian Ji -- The Horse Racing)中的动态规划以及贪心算法
- C/C++内存泄露
- Android Audio System
- 训练指南uva 11464
- Android OpenGL ES
- android学习笔记(一):第一个android程序
- Dom4j学习笔记--第二篇
- ANDROID音频系统散记之一:A2dpAudioInterface && Android Audio System