使用 Enable_If 條件選擇成員函數
任務是根據類別範本參數來決定成員函數的呼叫。以下程式碼片段嘗試實現此目的:
<code class="cpp">#include <iostream> #include <type_traits> template<typename T> struct Point { void MyFunction(typename std::enable_if<std::is_same<T, int>::value, T &>::type* = 0) { std::cout << "T is int." << std::endl; } void MyFunction(typename std::enable_if<!std::is_same<T, int>::value, float &>::type* = 0) { std::cout << "T is not int." << std::endl; } };</code>
但是,此程式碼無法編譯,並出現錯誤「'struct std::enable_if' 中沒有名為 'type' 的類型」。
SFINAE 實作
理解這個問題的關鍵在於替換失敗不是錯誤(SFINAE)的概念。 Enable_if 允許基於模板參數進行條件編譯。在這種情況下,當實例化成員函數時,模板參數 T 是已知的。因此,在實例化時評估條件並選擇相應的函數。
修正程式碼
為了修正這個問題,我們需要引入一個虛擬範本參數預設為 T。這允許 SFINAE 機制按預期工作。修改後的程式碼如下所示:
<code class="cpp">template<typename T> struct Point { template<typename U = T> typename std::enable_if<std::is_same<U, int>::value>::type MyFunction() { std::cout << "T is int." << std::endl; } template<typename U = T> typename std::enable_if<std::is_same<U, float>::value>::type MyFunction() { std::cout << "T is not int." << std::endl; } };</code>
防止明確成員函數特化
如HostileFork 所指出的,原始程式碼允許明確指定模板參數對於成員函數,這可能會導致不正確的結果。為了防止這種情況,我們可以新增一個 static_assert 來檢查是否提供了任何模板參數。這確保了始終根據模板參數 T 調用正確的成員函數。修改後的程式碼為:
<code class="cpp">template<typename T> struct Point { template<typename... Dummy, typename U = T> typename std::enable_if<std::is_same<U, int>::value>::type MyFunction() { static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!"); std::cout << "T is int." << std::endl; } template<typename... Dummy, typename U = T> typename std::enable_if<std::is_same<U, float>::value>::type MyFunction() { static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!"); std::cout << "T is not int." << std::endl; } };</code>
以上是如何使用'enable_if”根據範本參數選擇成員函數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!