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