为什么编译器期望在(具体)类型T
和const T
上对模板进行单独的特化?让我举个例子。我有一个按类类型Key
std::unordered_map<Key, Value> data;
并且要编译它必须在类型std::hash
上专门化Key
为
namespace std {
template<>
class hash<Key> { /* implementation */ };
}
但是,当我将地图类型更改为
时std::unordered_map<const Key, Value> data;
编译器没有使用我的专门化,而是选择了通用std::hash<T>
,这只是一个编译时断言,直到我专门std::hash<const Key>
。
除了使用const
限定地图密钥类型的效用之外,为什么const T
在这种情况下寻找专业化时不会崩溃到T
?
此外,模板类std::hash
(技术上)是否可以设计为允许这样的崩溃?
答案 0 :(得分:3)
我无法回答&#34;为什么&#34;,因为这是标准委员会的决定,毫无疑问他们有理由。
问题不仅限于自定义类型。您也无法实例化std::unordered_map<const std::string, int>
。
当然,使用显式const
类型作为标准关联容器的键类型很少有用,因为容器的value_type是std::pair<const Key, Val>
;无论声明的类型如何,键都是const。但我理解这与原始问题无关,而volatile
限定符会产生同样的效果。
可能不是吗?当然。它甚至不那么困难:
template<typename Key,
typename Val,
typename Hash = std::hash<typename std::remove_cv<Key>::type>,
typename KeyEq = std::equal_to<Key>,
typename Alloc = std::allocator<std::pair<const Key, Val>>>
using my_unordered_map = std::unordered_map<Key, Val, Hash, KeyEq, Alloc>;
唯一的区别是在std::remove_cv
模板参数的默认模板参数中使用Hash
。