繁体   English   中英

Static std::hash function 对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM