noob here。下面是一個類定義一個片段我在一本書中的例子來自翻過:算子[]歧義分辨率
double& operator[](int i);
double operator[](int i) const;
我的問題是:這是爲什麼不曖昧?編譯項目文件時,編譯器不會給出任何錯誤。 此外,在下面的(想象AnyClass包含例如valarray<double>
對象,我想直接訪問):
AnyClass test;
cout << test[2]
哪個版本編譯器使用?
noob here。下面是一個類定義一個片段我在一本書中的例子來自翻過:算子[]歧義分辨率
double& operator[](int i);
double operator[](int i) const;
我的問題是:這是爲什麼不曖昧?編譯項目文件時,編譯器不會給出任何錯誤。 此外,在下面的(想象AnyClass包含例如valarray<double>
對象,我想直接訪問):
AnyClass test;
cout << test[2]
哪個版本編譯器使用?
這並不含糊,因爲const
是簽名的一部分,可用於重載解析。因此,如果您在非常量對象上使用operator[]
,則它會在沒有const
的情況下選擇過載,因爲這是最具體的。如果你在一個const對象上使用它,它將使用const
選擇過載,因爲這是唯一適用的。
如果在const
對象上調用,則將使用const
版本,否則將使用另一個版本。
這就是編譯器解決歧義的方式。
Ohhhh,現在我明白了。感謝您的回答。第二個會爲const創建一個版本,以防例如我想查看某個元素。我無法理解爲什麼...所以,cout會使用第一個版本no?因爲測試不是一個常量(我也可以給它賦值,因爲它返回一個double&)。 – Kurospidey
AnyClass test;
const AnyClass const_test;
std::cout << test[2]; // calls operator[](int)
std::cout << const_test[2]; // calls operator[](int) const
感謝您的幫助 – Kurospidey
要理解這一點,你大多隻是需要認識到,在一個參數一個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
足以消除重載,所以這將有效地工作。
感謝您的回答。 – Kurospidey
謝謝你。完全忘記了這個隱含的論點。現在爲常量創建一個operator []版本是有意義的。 – Kurospidey