Как использовать typedef для универсального класса в C ++ - PullRequest
12 голосов
/ 13 июня 2011

Я пытаюсь использовать unordered_map. Но на некоторых серверах у нас нет библиотеки tr1. В этих случаях я хочу использовать карту. Итак, я хочу написать заголовочный файл, в котором я буду использовать одну из следующих строк.

typedef tr1::unordered_map hashmap;
typedef map hashmap;

Моя проблема в том, что я использую карты разных типов.

map<string, string>
map<string, int>
map <string, map<string,int>> ..etc

Если я могу использовать typedef для псевдонима или unordered_map в качестве hashmap, тогда я могу использовать карту как hashmap<string, string>, hashmap<int, int> в коде.

Есть ли способ сделать это, или, если есть какой-то лучший способ, пожалуйста, предложите мне.

Спасибо Винод

Ответы [ 3 ]

10 голосов
/ 13 июня 2011

Для этого вам нужно использовать так называемую метафункцию:

template <typename Key, typename T>
struct hashmap {
    typedef std::unordered_map<Key, T> type;
    // or
    //typedef std::map<Key, T> type;
};

, которая будет использоваться следующим образом:

hashmap<int, float>::type some_map;

Это очень распространенный шаблон.C ++ 0x делает это несколько проще, предоставляя улучшенный оператор using, но на данный момент это лучшее, что есть.

2 голосов
/ 13 июня 2011

Это будет возможно в c ++ 0x, но в настоящее время нет поддержки псевдонимов для специализированных шаблонов.См .: https://en.wikipedia.org/wiki/C%2B%2B0x#Template_aliases

В качестве обходного пути вы можете использовать макрос для замены типа карты, например:

#ifdef HAVE_TR1
#include <tr1/unordered_map>
#define HASH_MAP std::tr1::unordered_map
#else
#include <map>
#define HASH_MAP std::map
#endif

На неродственной заметке я бы назвал псевдоним«ASSOC_MAP» или даже просто «MAP» вместо «HASH_MAP».Последнее имя звучит так, как будто вы используете хэши, заставляя пользователя думать, что он имеет постоянные вставки и удаления, а не O (log N).

2 голосов
/ 13 июня 2011

C ++ 98 и 03 не предлагают поддержку шаблонов typedef, но вы можете сделать это с C ++ 0x.

В более ранних версиях вы можете использовать структуру шаблона со значением typedef, чтобы делать то, что вы хотите:

template <typename T1, typename T2>
struct hashmap
{
    typedef std::map<T1, T2> type;
};

Обратите внимание, что это было для иллюстративной цели, и вам также могут потребоваться дополнительные параметры шаблона, чтобы охватить оператор сравнения и распределитель.

...