2010-01-31 45 views
5

我正在寫作(作爲一種自我教學練習)一個簡單的STL-Like範圍。它是一個不可變隨機訪問「容器」。我的範圍,只保留其開始元素,元素的數量和步長(連續兩個元素之間的差值):類似STL的範圍,如果我這樣做會出現什麼問題?

struct range 
{ 
... 
private: 
    value_type m_first_element, m_element_count, m_step; 
}; 

因爲我的範圍不成立的元素,它計算所需元素使用以下:

// In the standards, the operator[] 
// should return a const reference. 
// Because Range doesn't store its elements 
// internally, we return a copy of the value. 
value_type operator[](size_type index) 
{ 
    return m_first_element + m_step*index; 
} 

正如你所看到的,我不是返回const reference爲標準說。現在,可以假定const reference和該元素的副本在使用標準庫中的非變異算法方面是相同的嗎?

關於這個問題的任何意見,非常感謝。


@Steve傑索普:你提到的迭代好點。其實,我用sgi as my reference。在該頁面的結束,它說:

假設X和Y是來自同一範圍的迭代器:

不變身份
x == y if and only if &*x == &*y

所以,沸騰一直到我問過的同一個原始問題:)

+0

如果你在operator []中創建了一個要返回的元素,然後返回了對它的引用,那麼這個引用是不是總是一個錯誤的引用,因爲這個實例會馬上超出範圍?
該標準討論的是容器中的參考,這不是容器。 – 2010-01-31 00:27:21

+0

@Chris我同意它不是一個真正的容器。這就是爲什麼我在上面第二句話中將「容器」放在雙引號之間。 – AraK 2010-01-31 00:31:37

+0

您可能想要查看boost :: iterator_range和boost :: sub_range獲取靈感:http://www.boost.org/doc/libs/1_41_0/libs/range/index.html – 2010-01-31 04:12:30

回答

1

標準算法實際上並不使用operator[],它們都是用迭代器來定義的,除非我忘記了一些重要的東西。是否計劃在operator[]之上爲您的「範圍」而不是迭代器重新實現標準算法?

在非變異算法確實使用迭代器的情況下,它們全都根據*it來定義,它們可以分配給任何需要分配給它的元素,或者對某些指定的操作或函數調用有效。我認爲所有或大多數此類行爲都具有價值。

我能想到的一件事是,您無法在需要非const引用的地方傳遞值。是否有任何需要非const引用的非變異算法?可能不會,只要任何函數參數等都有足夠的const

非常抱歉,我不能確定地說沒有奇怪的角落會出錯,但對我來說這聽起來基本上沒問題。即使存在任何小問題,您也可以在算法和標準算法之間的要求上有細微的差異來解決問題。

編輯:可能出錯的第二件事是採取指針/引用並保持它們太長。據我記得,標準算法不保持指針或引用的元素 - 這樣做的原因是,它是容器從而保證指針元素的有效性,迭代器只能告訴你,當迭代仍然有效(例如,當原始數據遞增時,輸入迭代器的副本不一定保持有效,而用於多遍算法的正向迭代器可以以這種方式複製)。由於算法沒有看到容器,只有迭代器,他們沒有任何理由認爲這些元素是持久的。

1

S中的項目預計TL容器會一直被複制;例如,考慮何時必須重新分配矢量。所以,你的例子很好,除了它只適用於隨機迭代器。但我懷疑後者可能是通過設計。 :-P

1

您是否希望您的範圍在STL算法中可用?第一個和最後一個元素不會更好嗎? (考慮到end()不是必需/使用的事實,你將不得不預先計算它的性能。)或者,你是否指望連續的元素(這是我的第二點)?

+0

'end()'可以非常簡單地計算出來:'m_first_element + m_step * m_element_count',所以它確實不是問題。我寫了一切neede來使'range'成爲一個*不可變*隨機存取容器,除了我在問題中所說的內容:) – AraK 2010-01-31 00:37:13

+0

這是我的問題的第二部分:是否可以將這個標準強加於內存管理部分的容器? – dirkgently 2010-01-31 00:40:52

+0

對不起,我沒有得到你在說什麼,你能不能詳細說明:) – AraK 2010-01-31 00:54:12

1

既然你把「容器」放在「引號」中,你可以做任何你想要的。

STL型的東西(在容器上的迭代器,各種成員函數。)返回引用因爲引用是左值和某些構建體(即,myvec會[I] = otherthing)可以編譯然後。想想std :: map上的operator []。對於const引用,我想這不是一個值來避免複製。

儘管這個規則一直被違反,但方便的時候。迭代器類通常會將當前值存儲在成員變量中,純粹是爲了返回引用或常量引用(如果迭代器是高級的,則此引用無效)。

如果你對這類東西感興趣,你應該檢查boost迭代器庫。

相關問題