クラス テンプレート メンバー関数で SFINAE が失敗する
テンプレート メタプログラミングで一般的に使用される、代替失敗はエラーではない (SFINAE) メカニズム。クラス テンプレートのメンバー関数に適用すると、特有の動作を示すようです。
問題
次のコード スニペットを考えてみましょう。
<code class="cpp">#include <type_traits> struct A{}; struct B{}; template <typename t> struct Foo { // Conditional enable bar() for T == A typename std::enable_if<:is_same a>::value>::type bar() {} // Conditional enable bar() for T == B typename std::enable_if<:is_same b>::value>::type bar() {} };</:is_same></:is_same></typename></type_traits></code>
このコードFoo クラス テンプレートで bar() の 2 つのオーバーロードを定義しようとします。SFINAE を使用して、T の値に基づいて各オーバーロードを条件付きで有効にします。ただし、コードは次のエラーでコンパイルに失敗します:
<code class="cpp">error: 'typename std::enable_if<:is_same b>::value>::type Foo<t>::bar()' cannot be overloaded</t></:is_same></code>
説明
SFINAE は通常、テンプレート引数に基づいてテンプレートの特殊化を有効または無効にするために使用されます。ただし、SFINAE は、推定された テンプレート引数、つまりオーバーロードの解決中に自動的に推定される引数にのみ適用されます。メンバー関数の場合、テンプレート引数は推定されず、クラスのインスタンス化時に明示的に指定されます。したがって、SFINAE はメンバー関数には適用できません。
解決策
この問題に対処するには、主に 2 つの方法があります。
<code class="cpp">template <typename t> void bar(Foo<t> void bar(Foo<t><ul><li> <strong>明示的なクラス テンプレートの特殊化を使用:</strong> 個別に定義以下に示すように、各オーバーロードのクラス テンプレート:</li></ul> <pre class="brush:php;toolbar:false"><code class="cpp">template <typename> struct Foo; template struct Foo<a> { void bar() {} }; template struct Foo<b> { void bar() {} };</b></a></typename></code>
以上がSFINAE がクラス テンプレートのメンバー関数で失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。