過載決議的步驟
過載解析的步驟是:
-
通過名稱查詢查詢候選函式。非限定呼叫將執行常規非限定查詢以及依賴於引數的查詢(如果適用)。
-
將候選函式集過濾為一組可行的函式。一個可行的函式,在呼叫函式的引數和函式所使用的引數之間存在隱式轉換序列。
void f(char); // (1) void f(int ) = delete; // (2) void f(); // (3) void f(int& ); // (4) f(4); // 1,2 are viable (even though 2 is deleted!) // 3 is not viable because the argument lists don't match // 4 is not viable because we cannot bind a temporary to // a non-const lvalue reference
-
選擇最有可行的候選人。如果
F1
中每個引數的隱式轉換序列不比F2
中相應的隱式轉換序列差,則可行函式F1
是比另一個可行函式F2
更好的函式,並且……:3.1。對於某些引數,
F1
中該引數的隱式轉換序列是比F2
中的引數更好的轉換序列,或者void f(int ); // (1) void f(char ); // (2) f(4); // call (1), better conversion sequence
3.2。在使用者定義的轉換中,從
F1
返回到目標型別的標準轉換序列是比F2
的返回型別更好的轉換序列,或者struct A { operator int(); operator double(); } a; int i = a; // a.operator int() is better than a.operator double() and a conversion float f = a; // ambiguous
3.3。在直接引用繫結中,
F1
與F2
具有相同型別的引用,或者struct A { operator X&(); // #1 operator X&&(); // #2 }; A a; X& lx = a; // calls #1 X&& rx = a; // calls #2
3.4。
F1
不是一個功能模板專業化,但F2
是,或template <class T> void f(T ); // #1 void f(int ); // #2 f(42); // calls #2, the non-template
3.5。
F1
和F2
都是功能模板專業化,但F1
比F2
更專業。template <class T> void f(T ); // #1 template <class T> void f(T* ); // #2 int* p; f(p); // calls #2, more specialized
這裡的訂購很重要。在模板與非模板檢查之前進行更好的轉換序列檢查。這導致轉發引用上的過載常見錯誤:
struct A {
A(A const& ); // #1
template <class T>
A(T&& ); // #2, not constrained
};
A a;
A b(a); // calls #2!
// #1 is not a template but #2 resolves to
// A(A& ), which is a less cv-qualified reference than #1
// which makes it a better implicit conversion sequence
如果最後沒有單一的最佳可行候選人,那麼這個呼叫是不明確的:
void f(double ) { }
void f(float ) { }
f(42); // error: ambiguous