为什么std :: hash是一个struct而不是一个函数?

时间:2013-11-24 19:20:57

标签: c++ c++11 std c++-standard-library stdhash

标准库将std :: hash实现为专门用于不同类型的模板结构。它的使用方式如下:

#include <iostream>
#include <functional>

int main()
{
    std::hash<int> hasher;
    std::cout << hasher(1337) << std::endl;

    return 0;
}

我的问题是这种设计选择背后的原因是什么。为什么它没有作为模板函数实现并使用如下:

#include <iostream>
#include <functional>

int main()
{
    std::cout << std::hash<int>(1337) << std::endl;

    return 0;
}

2 个答案:

答案 0 :(得分:17)

有多种原因,每种原因都足以让我们选择:

  1. 您可以部分地专门化类模板,但是您只能使用完全专用的功能模板(至少目前为止)。因此,您可以提供一整套相关模板参数的替换,std::hash<T>是一个类模板。请注意,部分重载没有用,因为需要以某种方式将哈希函数指定为无法通过重载函数完成的对象(除非它们是通过对象访问的,但这是区别对象的。)
  2. 无序关联容器使用静态实体进行参数化(如果特定类型支持,也可以动态自定义),使用类模板更容易实现。
  3. 由于用于散列函数的实体是可自定义的,因此可以选择使用类型或函数指针进行自定义。函数指针通常难以内联,而类型的内联成员函数对于内联来说是微不足道的,从而提高了简单函数的性能,例如计算简单的哈希值。

答案 1 :(得分:4)

模板函数不能部分专门用于类型,而std::hash专门针对不同类型作为类模板。

并且,在这种基于模板类的方式中,您可以执行一些元编程,例如访问返回类型和键类型,如下所示:

std::hash<X>::argument_type
std::hash<X>::result_type