2017-01-29 118 views
0

我正在學習C++。 我已經瞭解到引用允許我們避免複製。 所以我試圖得到一個向量的迭代器作爲引用來覆蓋它的元素。爲什麼不能將迭代器作爲C++的參考?

// simplified function 
std::vector<int>::iterator& GetIterator(std::vector<int>& vec) { 
    return vec.begin(); // compiler said that here is an error. 
} 

但編譯器給我一個錯誤消息,並建議使用const引用。 我不想使用const。 爲什麼不能得到非const引用? 或者如何避免迭代器的複製? 非常感謝。

+3

'vec.begin()'按值返回。所以想想這個參考文獻會提到什麼。 – juanchopanza

+1

你得到了什麼確切的錯誤信息? –

+0

爲什麼你想避免複製一個迭代器? – melpomene

回答

2

有時你可以使用一個參考,以避免拷貝 - 但在這裏你需要一個副本。當函數返回時,vec.begin()的結果是暫時的,不再存在。如果你想要的功能以外的價值 - 你這樣做 - 那麼需要一個副本。 (如果你在這裏成功地形成了一個參考,這將是一個「搖擺參考」,這不是一件好事)。

而且在任何情況下,許多類型被設計成被有效地複製,並且迭代器在其中。事實上,編譯器通常可以避免爲您複製,而無需您完成任何工作 - 這是其中一種情況。

所以沒有參考的代碼更容易,更正確,並且已經是最優的。

+0

謝謝你告訴我機制和如何做。 – mora

1

vec.begin();返回一個臨時對象並且是r值。您不能將l值引用綁定到r值。從GetIterator函數返回後,該臨時對象將被銷燬,並且您的引用將被懸掛。

按值返回(std::vector<int>::iterator)而不是參考。 Iterator s被設計成可複製和便宜的複製。還編譯器使用返回值優化以避免處理對象的成本。

+0

謝謝你告訴我爲什麼我的代碼錯了,怎麼辦。你的指示清晰銳利。 – mora

+0

@MRB *返回一個臨時對象並且是r值引用*。這不是一個右值參考,它只是一個右值。 – vsoftco

+0

@vsoftco謝謝。你是對的。 – MRB

0

正確的代碼

std::vector<int>::iterator GetIterator(std::vector<int>& vec) { 
    return vec.begin(); // compiler said that here is an error. 
} 

&是多餘的。

迭代器就像int*並獲得地址
std::vector<type>::iterator就是這樣。
所以vector.begin()就像&int所以你不能把它綁定到iterator&

+1

謝謝你告訴我如何修復代碼。 – mora

相關問題