2010-09-06 76 views
1

我使用Boost.Range爲這些數據傳遞一些數據和容器類。數據被加載到不同的線程中,並且在某些情況下可能尚未準備好。在這種情況下,容器使用默認的iterator_range進行初始化,因此包含單數迭代器。我正在做數據容器的分配和複製(因此是iterator_ranges)。但是,iterator_range拷貝構造函數調用begin()和end(),它會在原始單數時聲明。因此,不可能複製空的數據容器。將boost :: iterator_range指定爲單數範圍

有什麼辦法可以避免這個限制嗎?

爲什麼這個限制被實現?下面的工作很好,不應該範圍行爲類似?

typedef std::vector<int>::iterator iterator; 
iterator it; // Singular 
iterator it2 = it; // Works 

boost::iterator_range<iterator> range; // Singular 
boost::iterator_range<iterator> range2 = range; // Asserts in debug, but why? 

回答

3

如果「作品」,你的意思是,那是「不與我目前的編譯器版本和調用選項炸燬」,指定一個單一的迭代器可能的「工作」。 實際上,代碼

typedef std::vector<int>::iterator iterator; 
iterator it; // Singular 
iterator it2 = it; // Works 

導致不確定的行爲,所以你到你的編譯器中可能發生什麼的衝動。

C++標準是這樣說的關於它(段[lib.iterator.requirements]/5):

[...]大多數表達式的結果是不確定的對於奇異值;唯一的例外是將非奇異值賦值給保存奇異值的迭代器。在這種情況下,奇異值的覆蓋方式與任何其他值相同。可引用的和過去的最終值總是非單一的。

所以,最後範圍工作類似於單個迭代器。它只是不按你喜歡的方式工作。
我認爲最好的方法是在數據尚未準備好時使用空範圍(用非奇異迭代器顯式構造),而不是單一範圍。

+0

有趣的是,我不知道這是一個限制 - 並沒有看到效果。你知道這種行爲的原因嗎?對於GCC和MSVC來說,它似乎可以正常工作,因爲我們一直在我們的應用程序中執行此操作...:/ – larsmoa 2010-09-06 13:03:24

+0

未定義行爲的原因是它甚至不需要爲普通指針工作。當您查看單數指針值時,實現可能會陷入陷阱。 GCC和MSVC編譯器沒有任何優勢,並生成允許讀取f無效指針值的代碼。 – 2010-09-06 13:19:02

+0

讀取代碼時,也很容易認爲第二個迭代器已初始化。 – UncleBens 2010-09-06 14:39:00