为什么 std::allocator 要求 propagate_on_container_move_assignment 为真?

Why does std::allocator require propagate_on_container_move_assignment to be true?

根据当前标准 (20.7.9),std::allocator 有一个成员 propagate_on_container_move_assignment 设置为 true_type:

template class allocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
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 进行比较。是否有任何理由在移动分配时移动这些默认分配器?

我的回答是关于 C++11 的,正如你在标签中指出的那样:

如果特征不正确,则赋值操作需要执行运行时检查 分配器是否相等。是的,当然分配器总是相等的,但是代码不知道这一点并且仍然必须执行检查,因此您不能提供 noexcept 保证。 POCMA = true,可以静态知道自己会偷取资源,不会抛出。

C++14 使 std::allocator 具有 POCMA = true(在 LWG2103 中)。在 C++11 中是错误的。

C++17 引入了新特性 is_always_equal(在 N4258 中),即使 POCMA 为假,也允许对操作进行 non-throwing 异常规范。

(我认为分配器的设计从未完全完成是公平的,直到今天还没有人完全确定它们应该如何工作。)