"经典"的STL容器如std::vector
和std::map
将它们的分配器类型作为模板参数。这意味着std::vector<T, std::allocator<T>>
和std::vector<T, MyAllocator>
被认为是完全不同的类型。
另一方面,一些较新的支持分配器的类,如std::shared_ptr
和std::tuple
,使用类型擦除来“隐藏”关于分配器的信息,因此它不会成为类型签名的一部分。然而,std::unordered_map
(与shared_ptr
类似)保持了采用额外默认模板参数的经典方法。
问题:
把
std::vector<T, std::allocator<T>>
和std::vector<T, MyAllocator>
视为不同类型是否可取,还是仅仅是类型擦除在STL编写时不是一个众所周知的技术的副作用?以这种方式使用类型擦除是否存在缺点(如果有)?
在新的容器中应始终首选类型擦除分配器吗?
将
std::vector<T, std::allocator<T>>
和std::vector<T, MyAllocator>
视为不同类型是有意义的,因为这样可以确保在编译时对分配器进行静态类型检查,从而避免了错误的使用。使用类型擦除可能会导致一些运行时开销,因为需要动态分配内存来存储分配器对象。此外,它也可能会限制对分配器的直接访问。
是否应该使用类型擦除分配器取决于具体情况。如果需要快速原型设计或不需要特定的分配器功能,则可以考虑使用类型擦除。否则,显式指定分配器是更好的选择。