C++区分了5种匹配:
1.匹配中不转换或者只使用不可避免的转换(例如,从数组名到指针,函数名到函数指针,以及T到const T)
2.使用了整数的提升的匹配:(从char 到 int, short 到int , 以及 它们对应的unsigned 类型)以及float 到double,还有一个就是 bool到int。
3.使用了标准转换的匹配(例如 int到double, derived *到base*, unsigned int 到 int)
4.使用了用户定义转换的匹配;(包裹通过构建函数和转换操作)
5.使用了在函数声明里的省略号...的匹配
下面是我写的基本类型之间转换,从上到下级别越低。
1.char :char ->char
Char->int
Char->unsigned int、long、 float、 double、bool
2.int : int -> int
Int ->char 、unsigned int、long、 float、 double、bool
3.unsigned int : uint->uint
uint->char 、int 、long、 float、 double、bool
4.long: long->long
Long ->char 、int 、unsigned int、 float、 double、bool
5.float float-> float
Float->double
Float->char 、int 、unsigned int、long、 bool
6.double: double->double
Double->char 、int 、unsigned int、long、 float、 double
7.bool: bool->bool
Bool->int
Bool->char 、unsigned int、long、 float、 double
Unsigned int 到 int的转换不是类型的提升。
指针的转换:
指针之间没有标准转换(只能精确匹配),除了各种指针到void*指针的转换。
还忘记一个吧:
那就是0到指针的转换:
什么是0,c++中0可以使int 0, float 0等,还有一个拿就是空指针。
1.Long int 0到null指针的转换和long int 0到int 0的转换是一样的。
#define null 0l // null现在是一个long int
void f(int x);
void f(string *p);
f(null); // 错误!——歧义
同理:float 0到NULL的转换和到double 类型0是一样的。
2.0常量到各种指针NULL的转换是一样的。
Void f(int *x);
Void f(void *x);
F(0);//二义性,出错
还有就是NULL指针到0
1.NULL到int 0的转换要比到int *(double*、 float *)等 NULL的指针级别要高。
Void f(int *i);
Void f(int i);
F(NULL);//调用的是f(int);
2.NULL 到 除了int 0的转换级别(包裹 各种类型 和 指针)都一样。
Void f(int *i);
Void(long i);
F(NULL);//出错,有二义性。
在《effective C++》中一章《避免对指针和数字类型重载》有讲到怎么样对实现一个null对象来避免0和null在函数调用时产生歧义。
我摘抄了一部分:
const // 这是一个const对象...
class {
public:
template<class t> // 可以转换任何类型
operator t*() const // 的null非成员指针
{ return 0; } //
template<class c, class t> // 可以转换任何类型
operator t c::*() const // 的null成员指针
{ return 0; }
private:
void operator&() const; // 不能取其地址
// (见条款27)
} null; // 名字为null
用下面的程序来测试一下:
void f(int x);
void f(string *p);
f(null); //调用f(string *)。