1. 程式人生 > >C++primer第五版 函式過載及函式匹配

C++primer第五版 函式過載及函式匹配

函式過載即同一作用域內的幾個函式名字相同但形參列表不同,注意,不允許兩個函式除了返回型別外其他所有的要素都相同。

在大多數情況下,我們容易確定某次呼叫應該選用哪個過載函式,然而,當幾個過載函式的形引數量相等以及某些形參可以由其他型別轉換得來時,就比較複雜了。函式匹配首先是確定候選函式和可行函式,再尋找最佳匹配。

如果有且只有一個函式滿足下列條件,則匹配成功:

1. 該函式每個實參的匹配都不劣於其他可行函式需要的匹配;

2. 至少有一個實參的匹配優於其他可行函式提供的匹配。

如果在檢查了所有實參之後,沒有任何一個函式脫穎而出,則該呼叫是錯誤的,編譯器將報告二義性呼叫的錯誤。

以下程式是一個驗證:

// primer_6_6.cpp : Defines the entry point for the application.
// 函式匹配

#include "stdafx.h"
#include<iostream>
using namespace std;

int main()
{
	//定義幾個過載函式
	void f();
	void f(int);
	void f(int, int);
	void f(double,double = 3.14);
	//呼叫函式
	//cout << "f(2.56,42): ";
	//f(42,2.56);
	cout << "f(42): ";
	f(42);
	cout << "f(42,0): ";
	f(42,0);
	cout << "f(2.56,3.14): ";
	f(2.56,3.14);
	system("pause");
	return 0;
}
//定義過載函式
void f()
{
	cout << "f()" << endl;
}
void f(int)
{
	cout << "f(int)" << endl;
}
void f(int, int)
{
	cout << "f(int,int)" << endl;
}
void f(double,double = 3.14)
{
	cout << "f(double,double = 3.14)" << endl;
}

程式中首先定義了4個過載函式,這裡,函式只是作測試用,因此只輸出一條區分語句,其它什麼事情都不做。然後以多種方式對函式進行呼叫,分析並驗證哪個函式是最佳匹配,對於呼叫不合法的,分析其原因。

效果如下:

注意,f(42,2.56); 這句程式碼是被遮蔽掉的,因為編譯器會報錯。下面來分析一下為什麼呼叫不合法:

f(42,2.56);中,只考慮第一個實參42時我們發現f(int, int)能精確匹配,要想匹配f(double,double),int型別的實參必須轉換成double型別。顯然需要內建型別轉換的匹配劣於精確匹配,因此就第一個實參來說f(int, int)比f(double,double)更好。接著考慮第二個實參2.56,此時f(double,double)是精確匹配,想要呼叫f(int, int)必須將2.56從double型別轉換成int型別,因此就第二個實參來說,f(double,double)更好。編譯器最終將因為這個呼叫具有二義性而拒絕其請求:因為每個可行函式各自在一個實參上實現了更好的匹配,從整體上無法判斷孰優孰劣。即如下錯誤: