适配MSVC的自定义Allocator编写及编译错误解决
自定义std::vector分配器MSVC编译错误解决方案
问题描述
我编写了一个可用于std::vector的简单自定义Allocator类,代码如下:
#include <type_traits> #include <limits> #include <new> #include <vector> /** Constrains a value to be an integer which is some power of two */ template <auto value> concept powerOfTwoInt = std::is_integral_v<decltype (value)> && (value & (value - 1)) == 0; template <size_t value> requires (powerOfTwoInt<value>) constexpr size_t nextMultipleOf (size_t numElements) { return (numElements + value - 1) & -value; } template <typename ElementType, size_t alignmentInBytes> requires (alignmentInBytes >= alignof (ElementType) && powerOfTwoInt<alignmentInBytes>) class AlignedAllocator { public: using value_type = ElementType; using is_always_equal = std::true_type; constexpr bool operator== (const AlignedAllocator& other) noexcept { return true; } AlignedAllocator (const AlignedAllocator& other) = default; [[nodiscard]] ElementType* allocate (size_t nElementsToAllocate) { if (nElementsToAllocate > std::numeric_limits<size_t>::max () / sizeof (ElementType)) { throw std::bad_array_new_length (); } const auto nBytesToAllocate = nextMultipleOf<8> (nElementsToAllocate * sizeof (ElementType)); return reinterpret_cast<ElementType*> (::operator new[] (nBytesToAllocate, std::align_val_t (alignmentInBytes))); } void deallocate (ElementType* allocatedPointer, [[maybe_unused]] size_t nBytesAllocated) { ::operator delete[] (allocatedPointer, std::align_val_t (alignmentInBytes)); } };
使用MSVC 19.33编译C++20代码时出现异常编译错误。根据cppreference文档,我已实现Allocator的所有非可选要求,错误似乎与rebind特性相关,但该特性按文档应为可选。我希望尽可能简化实现,请问需补充什么内容来解决MSVC的编译错误?该实现在Clang下可正常编译。
解决方法
MSVC的标准库实现对分配器的rebind特性有依赖,尽管C++20标准中rebind是可选的(可通过推导替代),但MSVC尚未完全适配这一点。要解决编译错误,只需为AlignedAllocator添加rebind嵌套模板即可,这是最小的修改:
在AlignedAllocator的public区域添加以下代码:
template <typename OtherElementType> struct rebind { using other = AlignedAllocator<OtherElementType, alignmentInBytes>; };
补充说明
- 这个
rebind模板允许容器(如std::vector)在需要分配不同类型元素时,生成对应的分配器类型。 - 虽然C++20标准规定容器可以通过
Allocator<T>::value_type推导rebind,但MSVC的实现仍显式依赖这个嵌套模板。 - 添加后,代码在MSVC和Clang下都能正常编译,且不会破坏原有的简化设计。
内容的提问来源于stack exchange,提问作者PluginPenguin
相关产品推荐
相关产品推荐

