2010-09-27 47 views
2

我目前正在學習有關C++的併發性,並碰到使用線程向量,我相信這將在C++ 0x中可能。然而,我目前的編譯器似乎沒有移動感知容器的實現,所以我得到錯誤,因爲std::thread::thread(const std::thread&)被刪除,即我只能使用移動構造函數/移動作業與std::thread自定義分配器使用移動向量的線程

我是在寫一個自定義分配器使用

void MyAllocator::construct (pointer p, reference val) 
/* should be non-const reference to val because using move constructor? */ 
{ 
    new ((void*)p) T (std::move(val)); 
} 

而不是

void allocator::construct (pointer p, const_reference val) 
{ 
    new ((void*)p) T (val); 
} 

想我可以繞過這個問題是否正確?或者這個主題的其他變體(可能使用MyAllocator ::構造的重載)。

注意:這主要是一個短期的教育練習,並且可以很好地解決容器中的線程問題。在這種情況下,我只能使用MyAllocator。但是,也請指出任何可能實施此功能的圖書館,以便我可以對源代碼進行調查。

回答

2

如果你的編譯器不提供移動感知std::vector那麼你就必須要寫你自己的專業std::vector<std::thread>,而不是隻提供一個自定義的分配器。整個C++ 03 vector接口依賴於複製:push_back()複製元素; resize()拷貝初始化爲空元素作爲第二個參數傳遞的元素(即使這是缺省值T()); resize(),reserve(),insert(),erase()push_back()複製元素如果向量需要重新分配,或元素否則需要四處移動,等等。

這是一個很常見的問題,我已經包含了我的(商業)實現std::thread這樣的專業化。

2

規避問題的最簡單方法是分配堆上的線程並操作指向它們的指針。

檢查Boost Pointer Container庫:boost::ptr_vector<std::thread>在我看來你在找什麼。

0

std容器只需要可複製對象的需求與C++ 03容器接口的關係要比分配器實現更重要。 例如

vector<T> b(100); 
vector<T> a; 
a=b; 
assert(a==b); 

該標準保證我們a == b是真實的。但是,如果T不可複製,那麼在最好的情況下,a = b不會被編譯,最壞的情況是a = b是不確定的。此外,

a.push_back(T()); 

可能會導致一個分配新的空間,並在引擎蓋下有從舊複製到新的底層存儲的副本。此外,在C++ 03標準中沒有任何內容表示實際上必須調用allocator.construct,實際上很多(例如gcc)不會。

C++ 0x標準爲可移動類型的容器接口添加了新的成員函數,並闡明瞭如何使用operator =在其存在時的行爲。

見www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2486.pdf