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類型的重載函數了。

基礎還是要打紮實,書還是要多看幾遍啊。

 

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