2017-02-05 135 views
2

根據當前標準(20.7.9),std::allocator具有被設置爲true_type成員propagate_on_container_move_assignment爲什麼std :: allocator需要propagate_on_container_move_assignment爲true?

模板類分配器
{
公共:
的typedef爲size_t SIZE_TYPE;
typedef ptrdiff_t difference_type;
typedef T *指針;
typedef const T * const_pointer;
typedef T &參考;
typedef const T & const_reference;
typedef T value_type;
template struct rebind {typedef allocator other; };
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
[...]

std::allocator具有相比相等與任何其他std::allocator沒有數據成員和始終。是否有任何理由在移動分配時移動這些默認分配器?

+2

這不是C++ 11。在C++之後添加了'is_always_equal' 14。 –

回答

3

我回答相對於C++ 11,當你在標籤中標明:

如果特質是不正確的,那麼賦值操作需要就是否分配器進行運行時檢查是平等的。是的,當然分配器總是平等的,但代碼不知道,並且仍然需要執行檢查,因此您不能提供noexcept保證。隨着POCMA =真,你可以靜態地知道你會竊取資源,因此不會拋出。

使得std::allocator的C++ 14具有POCMA = true(在LWG2103中)。這在C++ 11中是錯誤的。

C++ 17引入了新特性is_always_equal(在N4258中),即使在POCMA爲假時也允許對操作進行非拋出異常規範。

(我認爲這是公平地說,分配器的設計從來沒有完全完成,並以這一天沒有人完全知道他們是如何工作的。)

+0

POCMA的原因是它影響容器元素的要求,而不僅僅是異常規範。如果沒有POCMA(或'is_always_equal'),您必須考慮元素移動的可能性。 –

+0

我有一個必然的問題:爲什麼不定義一個constexpr運算符==?爲什麼這個pocma是必要的。我會想象如果我使用這樣一個運算符作爲if語句的條件,那麼dead code消除會產生相同的代碼,就像我使用POCMA no的標籤分發一樣? – Oliv

+1

@Oliv constexpr'operator =='是可能的,並在[lwg 2108](https://cplusplus.github.io/LWG/lwg-defects.html#2108)中進行了討論。要使用它,你需要在SFINAE上下文中嘗試相等比較,看看它是否是一個有效的常量表達式(因爲不是所有的分配器都有一個constexpr'operator ==')。標籤調度更簡單。死代碼消除仍然適用於總是返回true的非constexpr'運算符=='。在實踐中,它沒有太大的區別。 –

相關問題