返回類型與模板參數中的SFINAE
假設我們有一個區分整數和浮點數的函數模板foo:
template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> auto foo(T) -> void; template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type> auto foo(T) -> void;
但是,當使用double呼叫時,此程式碼會失敗並出現錯誤value:
foo(3.4); // Error: no matching function for call to 'foo(double)'
為什麼這種方法會失敗?
在這種情況下,SFINAE 用於有條件地定義 foo 的回傳類型。但是,這違反了函數模板重載的規則,該規則不考慮預設模板參數。因此,編譯器將兩個 foo 模板視為具有相同簽名的相同函數。
使用表達式引用模板參數的替代方法
要解決此問題,我們可以改為在返回類型中使用引用模板參數的表達式:
template<typename T> auto foo(T) -> typename std::enable_if<std::is_integral<T>::value>::type; template<typename T> auto foo(T) -> typename std::enable_if<std::is_floating_point<T>::value>::type;
透過此修改,表達式std::enable_if 成為函式簽名,允許SFINAE 區分兩個foo 範本。
因此,第二個版本的 foo 可以正常工作,而第一個版本會觸發錯誤。
以上是為什麼 SFINAE 回傳類型失敗但模板參數成功?的詳細內容。更多資訊請關注PHP中文網其他相關文章!