2012-01-04 50 views
1

這是一個非常簡單的C++函數專用示例。我認爲它應該工作,但Visual Studio的編譯器給我一個不明確的消息。C++函數專精不允許?

template <class T> T min(T a, T b) { 
    if(a < b) return a; 
    else return b; 
} 

string min(string str1, string str2) { 
    if(str1.length() < str2.length()) return str1; 
    return str2; 
} 


void main(int argc, char* argv[]) 
{ 
    int n=12, p=15; 
    string str1= "monsieur", str2= "bonjour" ; 

    cout << min(n,p) << endl;   
    cout << min(str1, str2) << endl; 
} 

事實上,它說:「分(N,P)是ambigous,不知道哪個函數調用。這可能是一個微不足道的問題,但我還沒有想出這個問題。我試過下面的標題太:

template<> string min(string str1, string str2) 

和:

template<> string min<string>(string str1, string str2) 

有人可以幫助我走出

+1

告訴我們確切的錯誤消息和他們指的是哪一行(否則我們只能猜測,因爲你的示例代碼可能不是很小)。 – 2012-01-04 04:42:27

+3

使用min作爲名稱也可能會引起麻煩,請先嚐試類似'blah'的命令,以免與標準標識衝突。 – Gary 2012-01-04 04:46:33

回答

2

不需要轉換的非模板總是更好的匹配。也就是說,如果這些是min()的唯一定義,則不會有任何問題(即,將函數min重命名爲其他內容會消除不明確性)。含糊之處在於template <typename T> T const& std::min(T const&, T const&)與您的模板化版本之間。另一種解決方法是刪除using聲明,並明確從命名空間std限定名稱,即下面的代碼編譯好:

#include <iostream> 
#include <string> 

template <class T> T min(T a, T b) { 
    return a < b? a: b; 
} 

std::string min(std::string str1, std::string str2) { 
    return str1.length() < str2.length()? str1: str2; 
}  

int main() 
{ 
    int n=12, p=15; 
    std::string str1= "monsieur", str2= "bonjour" ; 

    std::cout << min(n,p) << "\n";   
    std::cout << min(str1, str2) << "\n"; 
} 

請注意:std::string版本的min()一個特例,但過載!當你這樣調用函數並不重要,它會根據預期選擇版本。然而,在調用函數時,同時明確指定模板參數也不會:

min(str1, str2);    // calls string overload 
min<std::string>(str1, str2); // calls the function template (*) 

(*)其實,min<std::string>(str1, str2)是,再次,曖昧與命名空間std版本由於參數依賴昂首。如果命名不同,它會調用模板版本。

如果你想真正專業化的功能,你會寫是這樣的:

template <> std::string min<std::string>(std::string, std::string) { ... } 

這就是說,這裏是無關的模糊性和專業化的節目數散記:

  • 在C++ main()總是必須聲明返回int。允許在main()中省略return語句,但是一些編譯器沒有得到正確的結果。對於便攜式代碼,您最好使用int的返回並僅返回0(或EXIT_SUCCESSdeclared in <stdlib.h>)。
  • 您幾乎可以肯定想要通過const參考:複製字符串並不是那麼昂貴,尤其是對於小的std::string s(因爲當前的std::string實現似乎使用小字符串優化),但它也不是免費的。如果對象相當大,則可能是性能問題。
  • 我認爲這只是測試超載/專業化。否則,std::string版本的min()是不明智的,因爲它以意想不到的方式運行。
  • 您的測試字符串被嚴重選擇,因爲他們不會顯示實際使用的超載/專業化。
  • std::endl被嚴重過度使用,並且做了與大多數人認爲它不同的事情:除插入換行符('\ n')外,還會刷新std :: ostream。後一部分令人驚訝,我發現它經常造成重大的性能問題。除非您真的打算沖洗流,否則請寫下\ n
+0

您的回答印象非常深刻!謝謝,我學到了很多東西! – Zonata 2012-01-04 05:59:27

2

你的問題是可能是由於min在其他地方的衝突定義(可能是標準庫)。嘗試將你的函數重命名爲my_min或其他東西。

更改函數的名稱使您的示例爲我正確編譯。

+0

可以認爲是問題所在。感謝你們爲這種微不足道的事件而感到不安。 – Zonata 2012-01-04 04:51:18

+0

不用擔心。理想情況下,不止一個人會從這個問題中學到一些東西! – 2012-01-04 04:54:16