[英]Static std::hash function objects
C++ 参考显示了如何定义自定义 hash function 对象的示例。 在此示例中,每次执行调用运算符时都会创建临时hash<string>
对象:
namespace std
{
template<> struct hash<S>
{
std::size_t operator()(S const& s) const noexcept
{
std::size_t h1 = std::hash<std::string>{}(s.first_name);
std::size_t h2 = std::hash<std::string>{}(s.last_name);
return h1 ^ (h2 << 1); // or use boost::hash_combine
}
};
}
我想,将它们设为 static 是否合理,因为它们不依赖于任何构造函数 arguments (默认可构造)并且基本上只是彼此的副本?
namespace std
{
template<> struct hash<S>
{
std::size_t operator()(S const& s) const noexcept
{
static std::hash<std::string> h;
std::size_t h1 = h(s.first_name);
std::size_t h2 = h(s.last_name);
return h1 ^ (h2 << 1); // or use boost::hash_combine
}
};
}
这种方法有什么缺点吗?
您认为创建这些 function 对象涉及什么? 您将它们分配在堆栈上,而不是堆上。 他们没有任何成员,因此他们的大小为零。 我猜编译器可能会在堆栈上为它们中的每一个保留一个词,以便为每个人提供一个唯一的this
指针......但这不需要任何额外的时间,我也希望编译器能够优化this
因为 class 没有任何成员,也没有对此做任何this
。
换句话说,编译器可能会发现std::hash<std::string>{}(s.first_name)
只是一个 function 调用并照此编译它。
我尝试了这两种方法和 Clang 11.0.1 与 -O3 至少在两种情况下生成完全相同的代码。
在 C++ static
变量中,内联 function 应在该 ZC1C4254Z5268E683945D1 的所有副本之间共享可以删除未使用的变量。
到目前为止,对于可执行文件来说不是问题,但在动态库中实现起来要困难得多,因为用户代码可能使用另一个编译器和/或不同的优化,因此可能会生成对该 object 的实际引用,即使它在库本身中未使用。
我希望某些平台上的一些编译器会在数据部分中保留 1 个额外的字节,并为此类变量生成冗余导出条目。
PS:ICC生成附加符号的示例(删除static
以查看差异)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.