首頁 >後端開發 >C++ >為什麼 SFINAE 在類別模板中使用成員函數時會失敗?

為什麼 SFINAE 在類別模板中使用成員函數時會失敗?

Patricia Arquette
Patricia Arquette原創
2024-11-05 04:26:02363瀏覽

Why Does SFINAE Fail with Member Functions in Class Templates?

類別模板中的成員函數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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn