我想用類型trait來檢查一個特定的類型是否可以使用標準庫的無序容器的缺省實例化,因此如果它具有std::hash
的有效特化。我認爲這將是一個非常有用的功能(例如,在通用代碼中使用std::set
作爲std::unordered_set
的失敗保護)。所以我想std::hash
沒有爲每種類型的定義,開始做以下SFINAE解決方案:(請原諒我的微薄SFINAE-能力,這是不是最好的解決辦法甚至是錯誤的)檢查類型是否可散
template<typename T> std::true_type hashable_helper(
const T&, const typename std::hash<T>::argument_type* = nullptr);
template<typename T> std::false_type hashable_helper(...);
//It won't let me derive from decltype directly, why?
template<typename T> struct is_hashable
: std::is_same<decltype(hashable_helper<T>(std::declval<T>())),
std::true_type> {};
但然後我知道,gcc 4.7和VC++ 2012定義std::hash
任何類型T
,只是static_assert
在非專業版本。但不是有條件地編譯它們(還有鐺3.1使用gcc 4.7的libstdC++)導致編譯錯誤的斷言失敗。這似乎是合理的,因爲我認爲static_assert
s不是由SFINAE處理的(對吧?),所以SFINAE解決方案似乎根本不可能。它更糟糕的是gcc 4.6
甚至在一般std::hash
模板中甚至沒有static_assert
模板,但是沒有定義它的()
運算符,導致嘗試使用它時出現鏈接器錯誤(這總是比編譯錯誤更糟糕,我無法想象任何方式將鏈接器錯誤轉換爲編譯器錯誤)。
那麼,有沒有符合標準的和可移植的方式來定義這樣的類型特徵返回如果一個類型有一個有效的std::hash
專業化,或許至少荷蘭國際集團在通用模板(在某種程度上轉化static_assert
錯誤到庫static_assert
一個SFINAE非錯誤)?
編輯:好吧,我對聲明* VC++ *編譯它是由一些不同的舊版本,其實* VC++ *行爲像* GCC *,窒息了'static_assert' –
看起來像海灣合作委員會的人都知道的問題。據說Gcc 4.8沒有這個靜態斷言,但他們考慮將來推出一個標準的實現,有點類似於Boost hash,其中實現被ADL拾取。 – Ichthyo
https://gcc.gnu.org/ml/libstdc++/2013-03/msg00029.html – Ichthyo