2015-03-31 60 views
7

我原以爲會這樣,但是在我的標準庫實現(gcc-4.8.2)中找不到這個。爲什麼std :: hash不是專用於std :: reference_wrapper的?

爲什麼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()); 
     } 
    }; 
} 
+3

也許是因爲如果你有一個引用包裝的容器,它是否應該散列引用或引用並不明顯,並提供一個標準的專業化將不得不選擇一個,並在這樣做混淆人。由於沒有提供,所以你不得不明確地表達你的意圖。 – Brian 2015-03-31 21:43:42

+0

如果不是引用,你會對'reference_wrapper'進行散列嗎?它只有成員是'get()',它返回'T&'(和函數調用操作符相同)。它幾乎完全是爲了允許引用被存儲在標準容器中。 – 2015-03-31 23:24:01

+1

指針,*即*,'std :: addressof(r.get())'。 – Brian 2015-03-31 23:37:12

回答

2

std::reference_wrapper主要是用來提供參考語義在實用程序,默認複製值,如std::bind

在容器中直接使用std::reference_wrapper基本上就像一個指針(除非它不能爲空)。指針(和智能指針)的散列遵循引用(即地址)語義。

當然你可以隨時提供自己的散列函數。如果您將其定義爲所有指針和智能指針的模板,那麼T*可能是值類型的更好選擇,而不是reference_wrapper<T>

請注意,如果您已經哈希對象並存儲散列,則可以通過將所有內容保留在unordered_map中來消除重複項。那麼價值標識和對象標識將是相同的。

相關問題