【发布时间】:2015-05-01 14:21:17
【问题描述】:
我原以为会是这样,但在我的标准库实现 (gcc-4.8.2) 中找不到它。
为什么std::hash 还没有专门用于std::reference_wrapper?
#pragma once
#include <functional>
namespace std
{
template<typename T>
struct hash<reference_wrapper<T>>
{
size_t operator()(const reference_wrapper<T>& r) const
{
return std::hash<T>()(r.get());
}
};
}
【问题讨论】:
-
也许是因为如果你有一个引用包装器的容器,它是否应该散列引用或所指对象并不明显,并且提供标准的专业化将不得不选择一个并且这样做会混淆人们。由于未提供,因此您必须明确表达您的意图。
-
如果不是参考,你会将
reference_wrapper散列在什么上面?它的唯一成员是get(),它返回一个T&(以及执行相同操作的函数调用运算符)。它的存在几乎完全是为了允许将引用存储在标准容器中。 -
指针,即,
std::addressof(r.get()). -
是的,您可以添加一个散列函数来散列对象本身,这就是您在问题中所写的。但是,如果标准库中提供了其中一个,则会混淆人们对另一个的期望。他们是否可以自己编写另一个版本是无关紧要的。
-
我认为智能指针的情况非常不同。要知道,引用是它所引用的对象的别名,引用包装器是类引用对象。另一方面,指针与它指向的对象明显不同,智能指针是一个类似指针的对象。很明显,智能指针的散列特化应该散列地址而不是对象。对于参考包装,它不是很清楚。