錯誤描述:
今天在使用Qt寫一個C++函數模板的測試程序的時候,編譯的時候,編譯的時候出現如下錯誤:
錯誤描述為:在main函數中,進行函數max()重載時,出現(ambiguous)含糊的,不明確的;引起歧義的使用;
因為第一次遇到這種錯誤,寫篇內容紀念一下吧。
測試代碼如下:
#include <iostream> using namespace std; template <typename T>//typename == class T max(T a,T b) { return a>b?a:b; } int main() { int a=1,b=2; cout<<max(a,b)<<endl; cout<<max(1,2)<<endl; cout<<max(2,3)<<endl; cout<<max(1.1f,2.2f)<<endl; cout<<max(1.11l,2.22l)<<endl; cout<<max('A','C')<<endl; //上面都是隱式的調用int,float.double.char類型的,而下面必須顯示的調用, //因為1是int類型的,而2.0是double類型的,此時,如果不明確指定數據類型,編譯器無法識別。 cout<<max<int>(1,2.0)<<endl; }
單從代碼看,我看不出什么錯誤,而且我記得當初學習C++模板的時候,也是這樣寫的,只不過,當初使用的IDE是VC6.0,難道環境不同。所以我把代碼貼到VC上,測試一下,完美的成功運行了。看來真是IDE不同的問題。但對於Qt,應該有解決辦法的,上網找了一下,原來是因為函數名沖突的問題,這里我先說下解決方法。
解決方法:
- 調用時聲明名字空間,把max(a,b);改成::max(a,b);前加::,避免沖突
- 改變函數名稱,把自定義的函數max改成myMax或其它。
造成問題的原因:
max函數與標准庫的std::max函數沖突。
看來Qt中已經有了標准的max()的函數了,我測試了一下,還真有這個函數。
問題深究:
從這個錯誤中,我們知道自己寫的函數名容易和標准庫或其他文件里的函數沖突,那么C++是怎么處理函數名沖突的呢?這就用到了命名空間。
名稱空間是一項c++de 特性,是用來解決在編寫大型程序中不同文件(廠商)中相同變量名問題。 例如:就像我編寫的函數max和標准的max,為了能夠准確調用其中一個max()函數,我們將這兩個函數分別放在不同在命名空間單元中。這樣就可以用 "命名空間::函數名" 的方式准確調用所需函數。
- ::max();//調用的自己寫的max()
- std::max();//調用的標准模板庫的max
我們經常會使用 using namespace std;
其中的std是c++在標准命名空間。
要讓程序訪問std有以下四種方法:
- 將using namespace std;放在函數定義之前,讓文件中所有的函數都能夠使用命名空間std中在元素。
- 將using namespace std;放在特定在函數定義中,讓該函數能夠使用命名空間std中元素。
- 在特定函數中使用using std::cout; 這樣的編譯指令,讓該函數使用命名空間std中所指定在元素,如 cout。這種方法在好處是,防止自己定義的變量名與std中在元素名重復。
- 完全不使用編譯指令using,在需要使用std中元素時,使用前綴std::。
通過上面的第4條,這個問題的解決方法還有一種,就是不使用 using namespace std;
,但是cout,cin等一些標准的庫函數就不能使用了,所以最好的辦法是修改函數名。