首頁 > 後端開發 > C++ > 表達式 SFINAE(替換失敗不是錯誤)在 C 中如何運作以及如何使用它來定義特徵並有條件地應用函數重載?

表達式 SFINAE(替換失敗不是錯誤)在 C 中如何運作以及如何使用它來定義特徵並有條件地應用函數重載?

DDD
發布: 2024-11-11 04:49:03
原創
728 人瀏覽過

How does Expression SFINAE (Substitution Failure Is Not An Error) work in C   and how can it be used to define traits and conditionally apply function overloads?

理解表達式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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板