2012-09-04 101 views
1

noob here。下面是一個類定義一個片段我在一本書中的例子來自翻過:算子[]歧義分辨率

double& operator[](int i); 
double operator[](int i) const; 

我的問題是:這是爲什麼不曖昧?編譯項目文件時,編譯器不會給出任何錯誤。 此外,在下面的(想象AnyClass包含例如valarray<double>對象,我想直接訪問):

AnyClass test; 
cout << test[2] 

哪個版本編譯器使用?

回答

7

這並不含糊,因爲const是簽名的一部分,可用於重載解析。因此,如果您在非常量對象上使用operator[],則它會在沒有const的情況下選擇過載,因爲這是最具體的。如果你在一個const對象上使用它,它將使用const選擇過載,因爲這是唯一適用的。

+1

謝謝你。完全忘記了這個隱含的論點。現在爲常量創建一個operator []版本是有意義的。 – Kurospidey

1

如果在const對象上調用,則將使用const版本,否則將使用另一個版本。

這就是編譯器解決歧義的方式。

+1

Ohhhh,現在我明白了。感謝您的回答。第二個會爲const創建一個版本,以防例如我想查看某個元素。我無法理解爲什麼...所以,cout會使用第一個版本no?因爲測試不是一個常量(我也可以給它賦值,因爲它返回一個double&)。 – Kurospidey

1
AnyClass test; 
const AnyClass const_test; 
std::cout << test[2];  // calls operator[](int) 
std::cout << const_test[2]; // calls operator[](int) const 
+1

感謝您的幫助 – Kurospidey

1

要理解這一點,你大多隻是需要認識到,在一個參數一個const足以消除歧義的電話:

#include <iostream> 

void foo(char* ptr) 
{ 
    std::cout << "mutable: " << ptr << std::endl; 
} 

void foo(const char* ptr) 
{ 
    std::cout << "const: " << ptr << std::endl; 
} 

int main() 
{ 
    const char* constHello = "hello"; 
    char mutableHello[] = "hello"; 
    foo(constHello); 
    foo(mutableHello); 
} 

此打印:

常量:你好
mutable:你好

編譯器會選擇最小限制的過載。因此,如果您在使用char*過載時使用char*,那麼它就是它會選擇的一個;但如果沒有,編譯器會決定將其轉換爲const char*是一種可行的轉換(反過來,顯然不是這樣)。

現在,非常簡單的事情是,所有方法都會通過指針this作爲任何函數的第一個參數。爲簡單起見,此參數是隱藏的。該方法末尾的const符合this參數。正如我們剛剛看到的,由於指針上的const足以消除重載,所以這將有效地工作。

+1

感謝您的回答。 – Kurospidey