簡體   English   中英

使用模板C ++“ const”神秘重載函數調用時

[英]when using templates C++ “const” mystery overloaded function call

我對以下代碼有疑問。 當我編譯它時,它會抱怨以下錯誤。 現在我的問題是,是否要刪除聲明中的“ const”並將其更改為only:

template<class T> T max( T& left, T& right);

一切正常,並且可以正確編譯/執行。 編譯器怎么認為該調用是模棱兩可的? 向前聲明不應該跟隨實現嗎?

==== start of error message====
max.cpp:10:34: error: call of overloaded ‘max(int, int)’ is ambiguous
max.cpp:10:34: note: candidates are:
max.cpp:5:21: note: T max(const T&, const T&) [with T = int]
/usr/include/c++/4.6/bits/stl_algobase.h:210:5: note: const _Tp& std::max(const _Tp&, const _Tp&) [with _Tp = int]
max.cpp:11:44: error: call of overloaded ‘max(double, double)’ is ambiguous
max.cpp:11:44: note: candidates are:
max.cpp:5:21: note: T max(const T&, const T&) [with T = double]

=======end of error message===

=============代碼從這里開始======

#include<iostream>

using namespace std;

template<class T> T max(const T& left, const T& right);

int main(void)
{

      cout<<"max int:"<<  max(1,4)<<endl;
      cout<<"max double:"<<  max(5.02,1.002)<<endl;

}

template<class T>
T max(const T& left, const T& right)
{

      return left > right? left:right;
}

你必須做:

  cout<<"max int:"<<  ::max(1,4)<<endl;
  cout<<"max double:"<<  ::max(5.02,1.002)<<endl;

由於在std名稱空間中定義了另一個max 您必須通知編譯器使用在全局名稱空間中定義的max ,即您定義的max 在此處查看實時示例: 功能模板演示

如果您查看在std名稱空間中定義的std::max

template <class T> const T& max (const T& a, const T& b);

它返回const引用並接受const引用參數,這就是為什么刪除const時會進行編譯的原因。 希望這會有所幫助。

std名稱空間已經內置了一個max,因此您不能using namespace std; 或將max函數放在您自己的名稱空間中。

namespace myNamespace {  
    //your max function  
}

我們已經在std名稱空間中定義了一些函數,例如max(),swap()qsort()。 因此,當您定義自己的功能時

max(const T& left,const T& right)

它與std名稱空間中的相同,因此出現錯誤。 因此,您可以按照以下步驟進行操作

  1. 使用范圍解析運算符:: max(x,y)調用函數

  2. 從函數中刪除const限定詞

正如其他人所寫的那樣,編譯器還在名稱空間std中另外找到了一個max函數。 現在,它試圖通過函數重載為您獲取最佳版本。 由於兩個簽名均相等,因此無法選擇最佳版本並抱怨。 現在,如果刪除const,則編譯器無法將整數(或雙精度)文字綁定到非const引用。 現在,它只有一個選擇,並具有std :: max功能。 您可以通過以下示例查看它:

#include <iostream>

namespace ns1 {

    template<class T>
    void doit(T const&) {
        std::cout << "ns1::doit" << std::endl;
    }
}

template<class T>
void doit(T&) {
    std::cout << "::doit" << std::endl;
}

int main() {
    using namespace ns1;
    int i=1;
    int const j=1;
    doit(1);
    doit(i);
    doit(i+1-1);
    doit(j);
    return 0;
}

就像int一樣,int編譯器僅在具有非const變量(i)時才必須選擇非const引用。 在其他情況下,它會從名稱空間ns1中選擇cont參考版本。 它甚至可以將臨時對象綁定到const引用(i + 1-1).max和std :: max也是如此。

編輯

我忘了說,如果您在聲明中刪除了const,編譯器選擇std :: max當然是正確的,但不是您的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM