SFINAE 類別模板成員函數失敗
替換失敗,不是錯誤(SFINAE) 機制,常用於模板元編程,當應用於類別模板成員函數時,似乎表現出特殊的行為。
問題
考慮以下程式碼片段:
<code class="cpp">#include <type_traits> struct A{}; struct B{}; template <typename T> struct Foo { // Conditional enable bar() for T == A typename std::enable_if<std::is_same<T, A>::value>::type bar() {} // Conditional enable bar() for T == B typename std::enable_if<std::is_same<T, B>::value>::type bar() {} };</code>
此程式碼嘗試在Foo 類別範本中定義bar() 的兩個重載,並使用SFINAE 根據T 的值有條件地啟用每個重載。但是,程式碼無法編譯,並出現以下錯誤:
<code class="cpp">error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded</code>
說明
SFINAE 通常用於啟用或停用基於模板參數的模板專業化。但是,SFINAE 僅適用於 推導的 模板參數,這意味著在重載解析期間自動推導的參數。對於成員函數,模板參數不是推導的,而是在實例化類別時明確指定的。因此,SFINAE 不適用於成員函數。
解
解決這個問題主要有兩種方法:
<code class="cpp">template <typename T> void bar(Foo<T><- A) {} template <typename T> void bar(Foo<T><- B) {}
<code class="cpp">template <typename> struct Foo; template <> struct Foo<A> { void bar() {} }; template <> struct Foo<B> { void bar() {} };</code>
以上是為什麼 SFINAE 對於類別模板成員函數失敗?的詳細內容。更多資訊請關注PHP中文網其他相關文章!