在該列表中,只有第二個引入了歧義,因爲函數 - 無論它們是否爲模板 - 都不能基於返回類型重載。
可以使用其他兩個:
template<typename X> void func(X x, int y);
將被使用,如果呼叫的第二個參數是一個整數,如func("string", 10);
template<class X, class Y, class Z> void func(X x, Y y, Z z);
會,如果你調用FUNC有三個使用參數。
我不明白爲什麼一些其他答案提到模板函數和函數重載不混合。他們當然會這樣做,並且有特定的規則如何選擇要調用的函數。
14.5.5
A function template can be overloaded with other function templates and with normal (non-template) functions. A normal function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.)
非模板化(或 「少模板」)過載,優選的模板,例如
template <class T> void foo(T);
void foo(int);
foo(10); //calls void foo(int)
foo(10u); //calls void foo(T) with T = unsigned
你的第一過載一個非模板參數也屬於這個規則。
幾個模板之間
考慮的選擇,更專業的比賽是首選:
template <class T> void foo(T);
template <class T> void foo(T*);
int i;
int* p;
int arr[10];
foo(i); //calls first
foo(p); //calls second
foo(arr); //calls second: array decays to pointer
你可以找到所有的規則更正式的描述標準的同一章(函數模板)
最後,在某些情況下,兩個或多個過載可能不明確:
template <class T> void foo(T, int);
template <class T> void foo(int, T);
foo(1, 2);
這裏的調用是不明確的,因爲兩個候選人都是同樣專業的。
您可以使用(例如)boost::disable_if
來消除這種情況。例如,我們可以指定當T = INT,則第二過載不應包含作爲過載候選:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
template <class T>
void foo(T x, int i);
template <class T>
typename boost::disable_if<boost::is_same<int, T> >::type
foo(int i, T x);
foo(1, 2); //calls the first
這裏庫在第二過載的返回類型產生「取代失敗」如果T = int,則將其從過載候選集合中刪除。
在實踐中,你應該很少遇到這樣的情況。
所有那些尾隨的';'字符都是毫無意義的。它們不是必需的,實際上使它看起來更加混亂。 – Omnifarious 2010-02-01 04:53:12