【The Cherno】令人疑惑的隐式转换
前言
本片文章仅记录观看视频时的疑惑,并提出自己的理解。
正文
使用隐式转换时容易引发一些令人疑惑的编译错误。为了正确理解隐式转换的用法,这里我要提出自己对隐式转换的定义:隐式转换是指==隐式的调用构造函数完成数据类型的转换==
- C++对隐式转换的规定是最多只允许一次隐式转换,也就是说不允许连续两次隐式的调用构造函数完成数据类型的转换。
- 隐式调用构造函数最基本的语法:
Entity e = 22
基本规则
在任何情况下,C++ 都只允许最多一次用户定义的隐式转换链。
这包括:
- 函数参数传递
- 构造函数参数传递
- 对象初始化
- 返回值转换
下面对视频中的例子进行解释
1 |
|

这里头为什么只有e4是编译错误的,我们对比着进行分析。
Entity只接收int数据类型和std::string类型进行构造。
首先,e1用int类型完成了一次隐式的调用构造函数,这是允许的。
而e4想用const char[7]或者说const char*(降级)来隐式的调用构造函数,注意我并没有在定义这种类型的构造函数只能接收std::string,而std::string确实可以接收const char*完成构造,但这又一次涉及到隐式的调用构造函数。总结来看,想从"Cherno"字符串转换为Entity类型需要先隐式的调用构造函数从const char*变为std::string,再隐式的调用一次构造函数从std::string变为Entity。总共两次隐式转换,这并不允许。
Entity e4 = (std::string = "Cherno"),括号里一次隐式,括号外一次隐式。两次隐式不允许
反观e2和e3为什么允许。因为e2和e3的构造语法是显式的调用构造函数,由于Entity只接收std::string,而std::string允许接收const char*,于是"Cherno"先隐式的调用构造函数转化为std::string,再显式构造为Entity。这其中只有一次隐式构造函数。
Entity e2(std::string = "Cherno"),括号里一次隐式,括号外一次显式。只有一次隐式
Entity e3 = Entity(std::string = "Cherno") ,括号里一次隐式,括号外一次显式。只有一次隐式

如果用上explicit关键字的话情况如下:

会发现e1不允许了,这很显然,因为Entity::Entity(int)必须显式的调用。
但为什么e2、e3却又允许呢,其实看上面的类型转换图就好理解了。因为只有在最后一次构造Entity是显式的,所以即使加上explicit关键字调用也符合规定。