在模板类中使用时,编译器错误与unordered_map

时间:2015-03-26 17:09:11

标签: 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>'

我想也许我的模板技巧在这里失败了,我做的不对。任何人都可以帮助识别这个问题吗?感谢。

3 个答案:

答案 0 :(得分:2)

无序容器的密钥类型需要为其定义的std::hash的特化,或者提供给容器的自定义散列函数。

由于您的容器位于模板中,使用通用密钥,因此提供自定义功能非常棘手;所以提供专业化,例如:

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

答案 1 :(得分:0)

unordered_map有一个默认的第三个参数,它是容器中包含的类的哈希。有时会有一个默认的实现,例如。对于intstd::string - 如果没有,则必须执行此操作。

答案 2 :(得分:0)

对于unordered_map,您必须通过提供std::hash<DeliveryMethodType> ob的实现来为您提供用户定义的键类型的哈希函数,方法是将您自己的哈希函数作为构造函数参数提供给{{1 }}