ホームページ  >  記事  >  バックエンド開発  >  SFINAE がクラス テンプレートのメンバー関数と連携しないのはなぜですか?

SFINAE がクラス テンプレートのメンバー関数と連携しないのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-11-04 21:55:02167ブラウズ

Why Doesn't SFINAE Work with Member Functions of Class Templates?

クラス テンプレートのメンバー関数に対して SFINAE (enable_if) が機能しないのはなぜですか?

C では、SFINAE (Substitution Failure Is Not An Error) を使用すると、次のことが可能になります。テンプレート引数のタイプに応じてコードを有効または無効にします。ただし、クラス テンプレートのメンバー関数を扱う場合、SFINAE は期待どおりに動作しないことがよくあります。

問題を示す例を次に示します。

<code class="cpp">#include <type_traits>

struct A {};
struct B {};

template <typename T>
struct Foo
{
    typename std::enable_if<std::is_same<T, A>::value>::type bar()
    {}

    typename std::enable_if<std::is_same<T, B>::value>::type bar()
    {}
};</code>

この例では、Foo は次のように定義します。 2 つのオーバーロードされたメンバー関数 bar()。最初のオーバーロードは T が A の場合に有効になり、2 番目のオーバーロードは T が B の場合に有効になります。ただし、このコードをコンパイルしようとすると、オーバーロードを解決できないことを示すエラー メッセージが表示されます。

このエラーの理由は、SFINAE が 推定された テンプレート引数に対してのみ機能するためです。クラス テンプレートのメンバー関数の場合、テンプレート引数は推定されず、明示的に指定されます。この問題を解決するには、次のいずれかの手法を使用できます:

  • 明示的なテンプレート引数を使用する:

    <code class="cpp">struct Foo
    {
      void bar(A) {}
      void bar(B) {}
    };</code>
  • メンバー関数内で std::enable_if を使用します:

    <code class="cpp">template <typename T>
    struct Foo
    {
      template<typename U = T>
      typename std::enable_if<std::is_same<U, A>::value>::type bar() {}
    
      template<typename U = T>
      typename std::enable_if<std::is_same<U, B>::value>::type bar() {}
    };</code>
  • 明示的なクラス テンプレートの特殊化を使用します:

    <code class="cpp">template <> struct Foo<A> { void bar() {} };
    template <> struct Foo<B> { void bar() {} };</code>

以上がSFINAE がクラス テンプレートのメンバー関数と連携しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。