Qt5.3編譯錯誤——call of overloaded ‘max(int int)’is ambiguous


錯誤描述:

今天在使用Qt寫一個C++函數模板的測試程序的時候,編譯的時候,編譯的時候出現如下錯誤:

image

錯誤描述為:在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,應該有解決辦法的,上網找了一下,原來是因為函數名沖突的問題,這里我先說下解決方法。


解決方法:

  1. 調用時聲明名字空間,把max(a,b);改成::max(a,b);前加::,避免沖突
  2. 改變函數名稱,把自定義的函數max改成myMax或其它。

造成問題的原因:

max函數與標准庫的std::max函數沖突。

看來Qt中已經有了標准的max()的函數了,我測試了一下,還真有這個函數。


問題深究:

從這個錯誤中,我們知道自己寫的函數名容易和標准庫或其他文件里的函數沖突,那么C++是怎么處理函數名沖突的呢?這就用到了命名空間。

名稱空間是一項c++de 特性,是用來解決在編寫大型程序中不同文件(廠商)中相同變量名問題。​ 例如:就像我編寫的函數max和標准的max,為了能夠准確調用其中一個max()函數,我們將這兩個函數分別放在不同在命名空間單元中。這樣就可以用 "命名空間::函數名" 的方式准確調用所需函數。

  • ::max();//調用的自己寫的max()
  • std::max();//調用的標准模板庫的max

我們經常會使用 using namespace std; 其中的std是c++在標准命名空間。

要讓程序訪問std有以下四種方法:

  1. 將using namespace std;放在函數定義之前,讓文件中所有的函數都能夠使用命名空間std中在元素。​
  2. 將using namespace std;放在特定在函數定義中,讓該函數能夠使用命名空間std中元素。​
  3. 在特定函數中使用using std::cout; 這樣的編譯指令,讓該函數使用命名空間std中所指定在元素,如 cout。這種方法在好處是,防止自己定義的變量名與std中在元素名重復。​
  4. 完全不使用編譯指令using,在需要使用std中元素時,使用前綴std::。

  通過上面的第4條,這個問題的解決方法還有一種,就是不使用 using namespace std; ,但是cout,cin等一些標准的庫函數就不能使用了,所以最好的辦法是修改函數名。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM