2017-02-05 73 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'运算符=='。在实践中,它没有太大的区别。 –

相关问题