考慮一個無鎖併發數據結構,其中pop()
操作需要返回一個項目或false
如果該cointainer是空的(而不是阻塞或投擲)。數據結構以用戶類型T
爲模板,該用戶類型可能很大(但也可以是輕量級的,並且我希望在任何情況下都能提高效率)。 T
必須至少可移動,但我不希望它必須是可複製的。輸出參數和移動語義
我在想這個函數的簽名應該是bool DS<T>::pop(T &item)
,所以這個項目被解壓爲一個out-parameter而不是返回值(用來表示成功或失敗)。但是,我如何才能將其傳遞出去?假設有一個基礎緩衝區。我會做 - 是否有意義進入參考輸出參數?缺點是用戶必須傳入一個默認構造的T,這會對有效的RAII產生一些影響,因爲如果函數失敗,結果是一個實際上未初始化其資源的對象。
另一種選擇是返回一個std::pair<bool, T>
而不是使用了參數,但需要再次是默認constructible T
後者持有失效的情況下,沒有資源,爲return std::make_pair(false, T)
。
第三種選擇是將項目返回爲std::unique_ptr<T>
,但這在T
是指針或其他輕量級類型的情況下會產生無用的開銷。雖然我可以在外部存儲實際項目的數據結構中存儲指針,但不僅會導致額外的解除引用和緩存未命中的損失,還會刪除直接存儲在緩衝區中的項目的自然填充,並有助於最大限度地減少生產者和消費者線程從擊中相同的緩存線。
這就是'boost :: optional',很快就是'std :: optional'。 – aschepler
您可以使用'std :: aligned_storage'返回可能包含或不包含對象的存儲。這基本上是'std :: optional'的意思 – KABoissonneault