理解表達式SFINAE
在C 程式設計環境中,表達式SFINAE(替換失敗不是錯誤)允許您有條件地應用函數基於函數宣告中表達式的有效性進行重載。
操作中的表達式SFINAE
考慮以下代碼示例:
示例1:
template <int I> struct A {}; char xxx(int); char xxx(float); template <class T> A<sizeof(xxx((T)0))> f(T) {}
f() 函數傳回一個結構體A,其參數我設定為呼叫xxx()的結果大小,範本參數T 的轉換值為(T)0.
範例2:
struct X {}; struct Y { Y(X) {} }; template <class T> auto f(T t1, T t2) -> decltype(t1 + t2); // #1 X f(Y, Y); // #2 X x1, x2; X x3 = f(x1, x2); // deduction fails on #1 (cannot add X+X), calls #2
在範例2 中,f() 函數重載允許添加數字類型(#1)以及從X 建構Y (#2)。當使用 x1 和 x2(X 物件)呼叫 f() 函數時,會選擇構造 Y 的重載,因為第一個重載對於 X 物件無效。
常見用例:Trait定義
表達式 SFINAE 通常用於特徵定義,它允許您根據類別中特定成員函數的存在來定義特徵。例如:
struct has_member_begin_test { template <class U> static auto test(U* p) -> decltype(p->begin(), std::true_type()); template <class> static auto test(...) -> std::false_type; }; template <class T> struct has_member_begin : decltype(has_member_begin_test::test<T>(0)) {};
has_member_begin 結構模板可用來檢查類別是否具有 begin() 成員函數。它使用表達式 SFINAE 來確定 begin() 表達式是否傳回有效的類型或表達式,如果有效則傳回 std::true_type,否則傳回 std::false_type。
重要提示:
表達式 SFINAE 是 C 語言中相對較新的新增內容,並非所有編譯器都完全支援它。如果您在程式碼中遇到表達式 SFINAE 的任何問題,請務必驗證您的編譯器版本是否支援它。
以上是表達式 SFINAE(替換失敗不是錯誤)在 C 中如何運作以及如何使用它來定義特徵並有條件地應用函數重載?的詳細內容。更多資訊請關注PHP中文網其他相關文章!