类型上的模板特化和const限定符

时间:2015-12-17 17:56:28

标签: c++ c++11

为什么编译器期望在(具体)类型Tconst 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(技术上)是否可以设计为允许这样的崩溃?

1 个答案:

答案 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

Live on coliru。)