C++ 函数重载 指针类型匹配到bool类型

如题,今天遇到一个很奇怪的问题,简化示例代码如下:

#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类型的重载函数了。

基础还是要打扎实,书还是要多看几遍啊。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章