SFINAEは、コンパイルエラーを引き起こすことなく、テンプレートのインスタンス化障害を優雅に処理できる強力なCテクニックです。それは、置換段階で無効なテンプレートのインスタンス化を破棄するコンパイラの能力を活用し、それらが存在しないかのようにそれらを扱います。重要なのは、無効な置換がハードエラーではなく、コンパイラーが静かに無視する障害につながるようにテンプレートを構築することです。これは通常、 std::enable_if
、 std::is_integral
、および<type_traits></type_traits>
のその他のタイプの特性などの手法を使用して達成されます。
一般的なアプローチは、テンプレートパラメーターリスト内でstd::enable_if
使用することです。 std::enable_if
ブール条件(多くの場合、タイプの特性に基づいて)と引数としてタイプを取得します。条件が真の場合、タイプは置換されます。それ以外の場合、パラメーターはテンプレートの署名から削除され、その特定のインスタンス化を効果的に無効にします。これにより、テンプレート引数として渡されたタイプに基づいて、関数またはクラスを条件付きで定義できます。
例えば:
<code class="c ">#include <type_traits> template <typename t typename="std::enable_if_t<std::is_integral_v<T">>> T addOne(T value) { return value 1; } template <typename t typename="std::enable_if_t<!std::is_integral_v<T">>> T addOne(T value) { return value 1.0; // Handle non-integral types differently } int main() { int i = addOne(5); // Uses the first overload double d = addOne(5.5); // Uses the second overload //std::string s = addOne("hello"); //This will not compile, no suitable overload found. return 0; }</typename></typename></type_traits></code>
この例では、 addOne
機能はsfinaeを使用して過負荷になります。最初のオーバーロードは、 T
が積分型の場合にのみ有効になります。 T
が積分タイプでない場合、2番目のオーバーロードが有効になります。どちらの条件を満たさないタイプが渡された場合、適切な過負荷は見つかりませんが、コンピレーションは失敗しません。
SFINAEは、さまざまなテンプレートメタプログラムシナリオで広範な使用を発見しています。一般的なユースケースには次のものが含まれます。
std::string
への変換をサポートする場合にのみ、 to_string()
メソッドを提供できます。はい、Sfinaeは、時間の安全性と効率の両方に大きく貢献しています。
コンパイル時間の安全性:型プロパティに基づいて条件付きコンピレーションを有効にすることにより、SFINAEは、互換性のないタイプのためにランタイムエラーにつながるコードのコンパイルを防ぎます。エラーは、実行時ではなくコンピレーション中に検出され、コードの全体的な堅牢性が向上します。
コンパイル時間効率: SFINAEにはコンパイル時間のオーバーヘッドが含まれますが、サポートされていないタイプの不必要なコードの生成を回避することにより、長期的に効率を改善できます。これにより、コンパイルされた実行可能ファイルのサイズが削減され、特に多数のテンプレートを扱う場合、実行時間が速くなります。デバッグと修正によりコストがかかるランタイムエラーを防ぐため、トレードオフは通常価値があります。
SFINAEは、テンプレートパラメーターリスト内のタイプ特性を使用して条件付きコンパイルを有効にします。タイプの特性は、コンパイル時にタイプに関する情報を提供するクラスまたはオブジェクトです。例には、 std::is_integral
、 std::is_floating_point
、 std::is_same
などが含まれます。これらの特性をstd::enable_if
(または同様のテクニック)と併用することにより、特定の条件(タイプの特性によって定義された)がmetである場合にのみインスタンス化されるテンプレートを作成できます。
std::enable_if
で表された条件がfalseである場合、コンパイラは対応するテンプレートパラメーターを削除し、置換障害につながります。この障害はエラー(SFINAE)ではないため、コンパイラは無効なインスタンス化を静かに無視し、条件付きコンパイルを効果的に実行します。これにより、不適切なタイプを使用したときにコンパイルエラーを引き起こすことなく、さまざまなタイプに優雅に適応する一般的なコードを作成できます。コンパイラは、テンプレート引数の有効な組み合わせのコードのみを生成します。
以上が高度なテンプレート手法では、CでSFINAE(代替障害はエラーではありません)を使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。