簡體   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