You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

适配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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 11:20:28