【问题标题】:What is the purpose of the STL allocator copy constructor requirementSTL 分配器复制构造函数要求的目的是什么
【发布时间】:2015-06-04 19:44:36
【问题描述】:

STL 对分配器有一些限制,其中包括: >

  1. a1 == a2 仅当分配器 a1 分配的存储可以通过 a2 释放时才返回 true。建立自反、对称和传递关系。不抛出异常。

  2. A a(b) 构造 a 使得 B(a)==b 且 A(b)==a。不抛出异常。 (注:这意味着所有与rebind相关的分配器都维护着彼此的资源,比如内存池)

http://en.cppreference.com/w/cpp/concept/Allocator

起初我错误地将要求 2 解释为:“A a(b) 构造 a 使得 a==b。”我认为这可能是一个常见错误,但考虑到对 2 的正确解释,它在哪些用例中实际上是有用的?我想大多数时候复制构造函数的主体都是空的。例如,它可以用于复制用于分配的文件指针吗?

【问题讨论】:

  • 我相信第二个要求是允许分配器将rebind 分配到与实例化时不同的类型。例如,list<int, allocator<int>> 将需要分配一些NodeType<int> 而不是ints,并且该子句确保allocator<int> 的行为与allocator<NodeType<int>> 相同。
  • 但是 typedef 还不足以重新绑定吗?
  • @JansenduPlessis typedef 对于无状态分配器来说已经足够了。您需要转换构造函数来传递状态(想想例如传递底层存储的池分配器)。 IOW:它适用于分配器不可默认构造的情况(或默认构造产生与复制不同的结果)

标签: c++ memory-management boost stl


【解决方案1】:

正如评论所指出的,分配器可以反弹到不同的类型。

大多数情况下¹,不同类型的分配器实例具有(隐式)转换,因此您可以传递Alloc<void>,其中预期Alloc<int>,反之亦然。

所以,当你这样做时

MyAlloc<int> ia;
MyAlloc<double> da;

bool equivalent = (ia == da);

你最终会做的是

bool equivalent = operator==(ia, da);

这会将da 隐式转换为MyAlloc&lt;int&gt;,除非存在operator== 的异构重载。

指定要求要求实现显式将rhs分配器转换为相同的分配器类型。这个

  • 避免意外遇到operator== 的异构重载和
  • 即使转换构造函数被标记为explicit,它仍然可以工作的好处。
bool equivalent = operator==(ia, MyAlloc<int>(da)); // or:
bool equivalent = operator==(da, MyAlloc<double>(ia)); // or:

同时这允许不同类型的分配器仍然比较非等价

¹需要检查是否指定为需求

【讨论】:

    猜你喜欢
    • 2019-07-03
    • 2017-03-26
    • 2013-07-28
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 2016-01-27
    相关资源
    最近更新 更多