【问题标题】:How can I use SFINAE to distinguish MyMap, std::map and std::unordered_map?如何使用 SFINAE 区分 MyMap、std::map 和 std::unordered_map?
【发布时间】:2020-03-26 09:51:59
【问题描述】:

我想创建一个可以使用任何地图实现的结构。 我们称之为MapHolder。目前,它看起来像这样:

template<template<class, class, class...> class MapType>
struct MapHolder
{
  MapType<int, int> m_map;
}

这适用于任何地图。

但我也想尽可能使用自定义比较器/分配器/哈希:

 // Works only with std::unordered_map
 MapType<int, int, my::hash<int>> m_map;

或者

 // Works only with std::map
 MapType<int, int, std::greater<>> m_map;

并且它只会使用其中一个类进行编译。

SFINAE 不能帮我让编译器选择最合适的声明吗(即第一个声明 MapHolder&lt;MyMap&gt;,第二个声明 MapHolder&lt;std::unordered_map&gt; 等等)?

【问题讨论】:

  • 为什么选择 SFINAE?你可以使用部分模板特化吗?
  • 我不知道您在哪里提供自定义比较器/哈希/分配器?
  • SFINAE,因为我不知道部分模板专业化 :) 我在元编程领域还很陌生。
  • 它在MapHolder 里面。我想为 STL 容器使用自定义分配器,并为 MyMap 类使用默认分配器。

标签: c++ compilation stl metaprogramming sfinae


【解决方案1】:

我会在这里使用部分模板特化。比如:

template<template<class, class, class...> class MapType>
struct MapHolder
{
private:
   template <typename> struct ThirdArgument;

   template <typename K,  typename V, typename C, typename A>
   struct ThirdArgument<std::map<K, V, C, A>>
   {
      using type = std::greater<K>;
   };

   template <typename K,  typename V, typename H, typename E, typename A>
   struct ThirdArgument<std::unordered_map<K, V, H, E, A>>
   {
      using type = std::hash<K>;
   };

public:
   MapType<int, int,
      typename ThirdArgument<MapType<int, int>>::type
   > m_map;
};

int main()
{
    MapHolder<std::map> m1;
    MapHolder<std::unordered_map> m2;
}

现场演示:https://godbolt.org/z/mEaFZv

【讨论】:

  • 好的,谢谢!但是那个不能与只接受 2 个模板的类 template&lt;class K, class V&gt;MyMap 一起使用(假设不是每个人都允许在他们的类中自定义散列或比较器)。我们不能只选择一个声明参数,而是选择整个声明吗?
  • @hououinyouma 然后,您可以对整个容器的规范使用部分特化。例如using type = std::map&lt;K, V, std::greater&lt;K&gt;, A&gt;; 代表std::mapusing type = std::unordered_map&lt;K, V, std::hash&lt;K&gt;, E, A&gt;; 代表std::unordered_map,以及using type = MyMap&lt;K, V&gt;; 代表您的地图。
  • 你能给我举个例子吗?我已经尝试过了,得到了一些类型/值不匹配的错误。
猜你喜欢
  • 1970-01-01
  • 2021-05-30
  • 2022-01-13
  • 2023-03-30
  • 2011-04-23
  • 1970-01-01
  • 2012-01-17
  • 2012-04-22
相关资源
最近更新 更多