【问题标题】:c++17 (c++20) unordered map and custom allocatorc++17 (c++20) 无序映射和自定义分配器
【发布时间】:2021-02-26 11:07:06
【问题描述】:

我对 map/unordered_map 和自定义分配器有一些问题 根据视觉工作室的文档,我的分配器看起来像这样。 我从基本类型派生了我的分配器,以确保正确设置所有模板类型,如 allocator::value_type。

template <class T>
class std_allocator : public std::allocator<T> {
   public:
    std_allocator() noexcept;
    std_allocator(const std_allocator& aOther) noexcept;
    template <class O>
    std_allocator(const std_allocator<O>& aOther) noexcept;

   public:
    void deallocate(T* const aPtr, const size_t aCount);
    T* allocate(const size_t aCount);
};

现在我定义了一个我的无序地图:

class Test {
   private:
    std::unordered_map<const SomeObject*,
                       void*,
                       std::hash<const SomeObject*>,
                       std::equal_to<const SomeObject*>,
                       std_allocator<std::pair<const SomeObject*, void*>>>
        mData;
};

不,我收到以下编译器错误: :\Development\Microsoft\Visual Studio 2019\VC\Tools\MSVC\14.28.29333\include\list(784,49): error C2338: list 要求分配器的 value_type 匹配 T(参见 N4659 26.2.1 [container.requirements.general]/16 allocator_type) 修复分配器 value_type 或定义 _ENFORCE_MATCHING_ALLOCATORS=0 以禁止此诊断。

从 unodered_map 标头看,模板看起来像这样

template <class _Kty, class _Ty, class _Hasher = hash<_Kty>, class _Keyeq = equal_to<_Kty>,
    class _Alloc = allocator<pair<const _Kty, _Ty>>>

从我的角度来看,它看起来是正确的。除了分配器中的对定义之外,我还尝试使用没有“const”的键。该错误表明我可以通过定义一个常量来禁用该错误,但我想这不是一个好主意。有人可以在这里给一些建议吗?

干杯

【问题讨论】:

  • 我不确定你是否定义了所有需要的成员函数,我似乎记得还需要更多。
  • 根据 c++17 文档,您只需要 allocate 和 deallocate 以及几个 c'tors。所有其他函数都标记为已弃用,并将在 c++20 中删除。我在向量中使用相同的分配器,它可以正常工作

标签: c++ stl c++17


【解决方案1】:

关键细节:

class _Alloc = allocator<pair<const _Kty, _Ty>>>

const 部分是关键。键本身必须是常量,这与指向常量对象的指针不同。指向常量对象的指针和指向(可能是 const)对象的常量指针之间是有区别的。

您的地图显然是由指向常量对象的指针作为键的。 gcc 10 编译这个:

#include <memory>
#include <unordered_map>

template <class T>
class std_allocator : public std::allocator<T> {
   public:
    std_allocator() noexcept;
    std_allocator(const std_allocator& aOther) noexcept;
    template <class O>
    std_allocator(const std_allocator<O>& aOther) noexcept;

   public:
    void deallocate(T* const aPtr, const size_t aCount);
    T* allocate(const size_t aCount);
};

class SomeObject {};

class Test {
   private:
    std::unordered_map<const SomeObject*,
                       void*,
                       std::hash<const SomeObject*>,
                       std::equal_to<const SomeObject*>,
                       std_allocator<std::pair<const SomeObject* const, void*>>>
        mData;
};

【讨论】:

  • 是的,我看到 const 是这里的关键。放置一个额外的 const 以使对象 const 而不是指针起作用。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 2014-12-05
  • 2020-07-03
  • 2020-04-16
相关资源
最近更新 更多