专门化hashmap模板

时间:2011-02-11 09:27:12

标签: c++ templates hash hashmap std

我在C ++中使用hash_map并希望为它提供简化的类型名称:

键类型和哈希功能始终相同。

stdext::hash_map<std::string, [MAPPED TYPE], CStringHasher>

但是,每次我声明一个将字符串映射到类型X的哈希映射时,我真的不想写所有这些。

  • 我可以编写简化此操作的模板或宏吗?

因此上述声明如下:

template<typename T> StringHashmap = stdext::hash_map<std::string, T, CStringHasher>

StringHashmap<int> mapA; //Maps std::string to int
StringHashamp<bool> mapB; //Maps std::string to bool

3 个答案:

答案 0 :(得分:5)

正如其他人所说,如果你可以使用C ++ 0x,那么模板别名就是你的选择:

template < typename MappedType >
using StringHashMap = stdext::hash_map< std::string, MappedType, CStringHasher >;

StringHashMap< int > mapA;
StringHashMap< bool > mapB;

(正如@MSalters所说,如果你有可用的C ++ 0x,你应该使用std::unordered_map。)

否则,您仍然可以使用通常的解决方法,即定义包含typedef的类模板:

template < typename MappedType >
struct StringHashMap
{
    typedef stdext::hash_map< std::string, MappedType, CStringHasher > type;
};

StringHashMap< int >::type mapA;
StringHashMap< bool >::type mapB;

此解决方案的一个缺点(在SO上产生很多问题)是您有时需要在StringHashMap< T >::type关键字前加typename前缀以断言该名称有效表示类型的编译器。我不会在这个答案中详述这个主题,您可以查看this FAQ,特别是接受的答案,以获取更多信息。 (感谢@sbi引起这件事。)

答案 1 :(得分:2)

使用当前版本的C ++(C ++ 03),确实没有一种好方法可以做到这一点。你可以试试像

这样的东西
#define StringHashMap(type) stdext::hash_map<std::string, type, CStringHasher>

但是如果您尝试使用逗号指定模板类型,则会遇到麻烦,如下所示:

StringHashMap(pair<int, string>) myMap; // Error!

这会失败,因为预处理器会将其标记为

StringHashMap((pair<int), (string>)) myMap; // Error!

这不是你想要的。但是,如果你不打算这样做,你应该没问题。您也可以使用typedef来绕过它:

typedef pair<int, int> IntPair;
StringHashMap(IntPair) myMap; // Okay

如果您允许使用C ++ 0x功能,您可以使用声明模板,如下所示:

template <typename T>
    using StringHashMap = stdext::hash_map<std::string, T, CStringHasher>;

不幸的是,C ++ 03没有像这样的“模板typedef”功能,所以你必须使用更新的编译器,并且没有那么好的可移植性保证。

嘿,等一下!我的名字是templatetypedef,这是我第一次在Stack Overflow上写过这个短语的答案!你刚刚过夜。 : - )

答案 2 :(得分:1)

如果您使用的是C ++ 0x,那么模板typedef就是为了完成这类工作而设计的:

http://en.wikipedia.org/wiki/C%2B%2B0x#Template_aliases