類別模板中的成員函數SFINAE:詳細說明
在C 世界中,SFINAE(替換失敗不是錯誤)使透過防止編譯期間的實例化錯誤來最佳化模板。然而,在處理類別模板的成員函數時,SFINAE 的行為可能會出現意外。
成員函數 SFINAE 的問題
考慮以下程式碼:
<code class="cpp">template <typename T> struct Foo { typename std::enable_if<std::is_same<T, A>::value>::type bar(); typename std::enable_if<std::is_same<T, B>::value>::type bar(); };</code>
與預期相反,此程式碼會導致錯誤訊息。 SFINAE 沒有如預期用於類別模板中的成員函數。
SFINAE 和推導模板參數
問題的關鍵在於 SFINAE 對推導模板參數的依賴。僅當從函數呼叫推導模板參數時它才有效。對於成員函數,不會推導出模板參數,而是明確提供。
使用推導參數的解
為了解決這個問題,我們可以修改程式碼如下:
<code class="cpp">template<typename T> struct Foo { template<typename U = T> typename std::enable_if<std::is_same<U,A>::value>::type bar() { } template<typename U = T> typename std::enable_if<std::is_same<U,B>::value>::type bar() { } };</code>
現在,當呼叫Foo( )(x) 時,編譯器會推導出模板參數T 並根據x 選擇正確的重載。這種方法允許 SFINAE 按預期運作。
或:明確類別模板專業化
如果類別的結構至關重要且無法修改,則替代解決方案包括明確類別模板特化:
<code class="cpp">template <typename> struct Foo; template <> struct Foo<A> { void bar() {} }; template <> struct Foo<B> { void bar() {} };</code>
這裡,編譯器根據提供的型別確切地知道要實例化哪個特化。它不依賴 SFINAE 進行專業選擇。
以上是為什麼 SFINAE 在類別模板中使用成員函數時會失敗?的詳細內容。更多資訊請關注PHP中文網其他相關文章!