如题,今天遇到一个很奇怪的问题,简化示例代码如下:
#include <iostream>
#include <string>
class TestClass{
public:
void TestFunction(const std::string& test_string)
{
std::cout << "string function!" << std::endl;
}
void TestFunction(bool test_bool)
{
std::cout << "bool function!" << std::endl;
}
};
int main()
{
TestClass tmp;
tmp.TestFunction("123456");
return 0;
}
可以看到TestClass类中TestFunction进行了重载,参数分别为string和bool,此时如果如示例中传入了"123456"这一字面常量时,实际上传入的是const char指针类型。类似于如下
const char* tmp_string = "123456";
tmp.TestFunction(tmp_string );
期望的匹配是该类型触发隐式转换构造为string,从而匹配string参数的重载函数。但是实际上匹配到的是bool参数的函数。除非显式强转如:
tmp.TestFunction(std::string("123456"));
查了下《C++ primer》才知道,基础知识有缺漏。
C++编译时,编译器会根据传入实参进行重载函数匹配,此时可能发生实参类型到形参类型的转换,这里编译器将实参类型到形参类型的转换分成几个等级,排序如下:
1.精确匹配:
-
实参类型和形参类型相同
-
实参从数组类型或函数类型转换成对应的指针类型
-
向实参添加顶层const或者从实参中删除顶层const
2.通过const转换实现的匹配
底层const的添加,如:
int i;
void testFunction(cosnt int* test_int);
int main()
{
testFunction(&i);
}
3.通过类型提升实现的匹配
类型提升为类型长度宽度的提升,如short->int,float->double。
4.通过算数类型转换或指针转换实现的匹配
算数类型转换如int->double,需要与类型提升区分开。
指针转换除了各种指针类型之间的转换,还存在一种指针类型向bool类型自动转换的机制,如果指针的值为0,转换结果为false,否则转换结果是True,指针不存在转为bool外其他非指针类型的隐式转换。
5.通过类类型转换实现的匹配
类类型转换一般为子类向父类转换,或者形参类构造函数支持传入形参类型,例如开头处提到的"1234"->std::string。
上述优先级从1到5依次降低,1-4可以认为是C++内置转换,5为自定义转换,则本次遇到的坑"123456"->bool属于优先级4,而“123456”->std::string 属于自定义的优先级5,自然匹配到bool类型的重载函数了。
基础还是要打扎实,书还是要多看几遍啊。