STL是充滿了這樣的定義:const和非const函數的重載是如何工作的?
iterator begin();
const_iterator begin() const;
由於返回值不參與重載決議,唯一不同的是這裏的功能是const
。這是重載機制的一部分嗎?什麼是編譯器的解決像線算法:
vector<int>::const_iterator it = myvector.begin();
STL是充滿了這樣的定義:const和非const函數的重載是如何工作的?
iterator begin();
const_iterator begin() const;
由於返回值不參與重載決議,唯一不同的是這裏的功能是const
。這是重載機制的一部分嗎?什麼是編譯器的解決像線算法:
vector<int>::const_iterator it = myvector.begin();
在你給的例子:
vector<int>::const_iterator it = myvector.begin();
如果myvector
不爲const begin()
非const版本將被調用,你將依靠從迭代器到const_iterator的隱式轉換。
是的,const
修改影響超載。如果myvector
是const
在這一點上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
編譯器的「算法」是這樣的: 類X的每個成員函數都有一個類型爲X的隱式參數(我知道,大多數人認爲它是X *,但是標準狀態,爲了解決超載問題,我們假定它是一個參考)。對於const函數,參數的類型是const X &。因此,如果一個成員函數被稱爲兩個版本,const和non-const都是可行的候選者,那麼最好的匹配就像在其他重載解析的情況下一樣。沒有神奇:)
謝謝,這是有用的,但是我的問題是(錯誤的)假設const變量被調用,因爲它被分配的變量的類型。 @awoodland解釋了這個 – davka 2011-02-24 11:18:12
爲什麼引用而不是指針和那個只能用於重載的解析,有什麼非明顯的原因呢? – 2018-01-30 05:07:58
從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
。
值得一提的是,C++ 允許const的方法/函數重載(例如FOO()const的),但不是常量參數超載(例如巴(INT A)和bar(const int的A))。
編譯器確定對象變量是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);
哦,這解決了難題...所以,有一個轉換涉及。謝謝! – davka 2011-02-24 11:11:50