c++ - 在模板类中使用 unordered_map 时出现编译器错误

标签 c++ templates c++11

由于我的例子有点复杂,我在这里放了一个示例来演示错误(下面也会内联代码): http://coliru.stacked-crooked.com/a/a426995302bda656

#include <functional>
#include <unordered_map>
#include <memory>

enum class DeliveryMethodType
{
  POST_MASTER,
  BUBBLE,
};

class IDeliveryMethod
{
};

class BubbleDelivery : public IDeliveryMethod
{
};

template<typename Key, typename Interface>
class GenericFactory
{
public:

   using FactoryMethod = std::function<std::unique_ptr<Interface> ()>;

   static Key const& Register(Key const& key, FactoryMethod creator)
   {
      s_factoryMethods.insert({key, creator});
      return key;
   }

   static std::unique_ptr<Interface> Create(Key const& key)
   {
      std::unique_ptr<Interface> obj;

      auto it = s_factoryMethods.find(key);
      if (it != s_factoryMethods.end())
      {
         obj = it->second();
      }

      return obj;
   }

private:
   static std::unordered_map<Key, FactoryMethod> s_factoryMethods;
};

template<typename Key, typename Interface>
std::unordered_map<Key, typename GenericFactory<Key, Interface>::FactoryMethod>
GenericFactory<Key, Interface>::s_factoryMethods;

using DeliveryMethodFactory = GenericFactory<DeliveryMethodType, IDeliveryMethod>;

static auto key = DeliveryMethodFactory::Register(DeliveryMethodType::BUBBLE, []() {
      return std::unique_ptr<IDeliveryMethod>(new BubbleDelivery);
});

int main()
{
}

我的设计目标是创建一个通用的静态工厂类。每个翻译单元将(在静态初始化时)调用 Register() 方法,以针对所需的键和工厂方法类型调用 GenericFactory 的特定特化。

我收到以下编译器错误,我不确定如何解决。

error: implicit instantiation of undefined template 'std::hash<DeliveryMethodType>'

我想也许我的模板技巧在这里失败了,我没有做正确的事情。任何人都可以帮助确定这里的问题吗?谢谢。

最佳答案

无序容器的键类型需要为其定义的 std::hash 的特化,或者为容器提供的自定义哈希函数。

由于您的容器位于模板中,具有通用键,因此很难提供自定义函数;所以提供特化,例如:

namespace std {
    template <> struct hash<DeliveryMethodType> {
        size_t operator()(DeliveryMethodType x) const {
            return hash<int>()(static_cast<int>(x));
        }
    };
}

关于c++ - 在模板类中使用 unordered_map 时出现编译器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29284706/

相关文章:

c++ - 为什么这个 std::map 键提取函数需要 --std=c++?

c++ - QT 中 QDoubleSpinBoxes 的多个范围

c++ - 试图了解C++ STL容器的初始化

c++ - 用于测试 func(args) 是否格式正确且具有必需的返回类型的特征

c++ - 如何将模板化类专门用于数据类型分类?

c++ - C++ 中的编译问题 (CodeBlocks 13.12)

c++ - 什么时候更喜欢 lambda 中的显式捕获而不是隐式捕获?

c++ - 定义静态常量结构

c++ - 将小部件添加到 QFileDialog

c++ - 具有可变数量的模板参数的简单方法