Как я могу использовать SFINAE для различения guish MyMap, std :: map и std :: unordered_map? - PullRequest
0 голосов
/ 26 марта 2020

Я хочу создать структуру, которая может использовать любую реализацию карт. Давайте назовем это MapHolder. В настоящее время это выглядит так:

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

И это будет работать с любой картой.

Но я также хочу использовать пользовательский компаратор / распределитель / ха sh, когда это возможно:

 // 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<MyMap>, затем для MapHolder<std::unordered_map> и т. д.)?

1 Ответ

1 голос
/ 26 марта 2020

Я бы использовал частичную специализацию шаблона здесь. Что-то вроде:

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.

...