【发布时间】:2015-12-17 17:56:28
【问题描述】:
为什么编译器期望在(具体)类型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(技术上)是否可以设计成允许这样的崩溃?
【问题讨论】:
-
仅仅是因为
T和const T在定义上是不同的类型(除非T已经是const)。std::hash可以被设计成这样折叠,是的,但显然不是。还是个好问题! -
std::unordered_map<const std::string, int>也不编译。因此,您不需要自定义键类型来注意到问题。但通常情况下,不需要在std::{unordered_,}{multi,}map中使用显式的const类型,因为键始终是const。 -
@rici:关于
string键的好点!至于密钥类型的 const-ness,我确实同意,但这不是我的重点。 -
@kkm:明白。我将评论提升为答案;希望它以某种方式有所帮助。如果你想要
std::unordered_map<const Key, Val>,你总是可以明确说明哈希参数:std::unordered_map<const Key, Val, std::hash<Key>>可以正常工作。答案中提出了更通用的解决方案。