2011-02-24 72 views
13

STL是充滿了這樣的定義:const和非const函數的重載是如何工作的?

iterator begin(); 
const_iterator begin() const; 

由於返回值不參與重載決議,唯一不同的是這裏的功能是const。這是重載機制的一部分嗎?什麼是編譯器的解決像線算法:

vector<int>::const_iterator it = myvector.begin(); 

回答

10

在你給的例子:

vector<int>::const_iterator it = myvector.begin(); 

如果myvector不爲const begin()非const版本將被調用,你將依靠從迭代器到const_iterator的隱式轉換。

+1

哦,這解決了難題...所以,有一個轉換涉及。謝謝! – davka 2011-02-24 11:11:50

4

是的,const修改影響超載。如果myvectorconst在這一點上const版本將被稱爲:

void stuff(const vector<int>& myvector) 
{ 
    vector<int>::const_iterator it = myvector.begin(); //const version will be called 
} 

vector<int> myvector;  
vector<int>::const_iterator it = myvector.begin(); //non-const version will be called 
9

編譯器的「算法」是這樣的: 類X的每個成員函數都有一個類型爲X的隱式參數(我知道,大多數人認爲它是X *,但是標準狀態,爲了解決超載問題,我們假定它是一個參考)。對於const函數,參數的類型是const X &。因此,如果一個成員函數被稱爲兩個版本,const和non-const都是可行的候選者,那麼最好的匹配就像在其他重載解析的情況下一樣。沒有神奇:)

+0

謝謝,這是有用的,但是我的問題是(錯誤的)假設const變量被調用,因爲它被分配的變量的類型。 @awoodland解釋了這個 – davka 2011-02-24 11:18:12

+0

爲什麼引用而不是指針和那個只能用於重載的解析,有什麼非明顯的原因呢? – 2018-01-30 05:07:58

3

從C++標準(§13.3.1候選功能和參數列表):

For non-static member functions, the type of the implicit object parameter is 「reference to cv X」 where X is the class of which the function is a member and cv is the cv-qualification on the member function declaration. [Example: for a const member function of class X, the extra parameter is assumed to have type 「reference to const X」. ]

所以,你的情況,如果myvector對象是const編譯器會挑begin版本,具有reference to const vector類型的隱式對象參數,它是常量版本begin

1

值得一提的是,C++ 允許const的方法/函數重載(例如FOO()const的),但不是常量參數超載(例如巴(INT A)和bar(const int的A))。

1

編譯器確定對象變量是const或在編譯時間

然後它選擇相應的過載,以及任何返回類型它有。

class C { 
    public: 
     int f() { return 1; } 
     float f() const { return 1.5; } 
}; 

// Non const. 
C c; 
assert(c.f() == 1); 

// Convert variable const at compile time. 
assert(const_cast<const C&>(c).f() == 1.5); 

// Same as above but with an explicit reference. 
const C& d = c; 
assert(d.f() == 1.5); 

// Analogous but with a new const object from the start. 
const C e; 
assert(d.f() == 1.5); 
相關問題