ホームページ  >  記事  >  バックエンド開発  >  「enable_if」を使用してテンプレートパラメータに基づいてメンバー関数を選択する方法

「enable_if」を使用してテンプレートパラメータに基づいてメンバー関数を選択する方法

DDD
DDDオリジナル
2024-10-25 19:06:39763ブラウズ

How to Select a Member Function Based on a Template Parameter Using `enable_if`?

Enable_If 条件を使用したメンバー関数の選択

このタスクは、クラス テンプレート パラメーターに基づいてメンバー関数の呼び出しを決定することです。次のコード スニペットはこれを実現しようとします:

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

template<typename T>
struct Point
{
  void MyFunction(typename std::enable_if<std::is_same<T, int>::value, T &>::type* = 0)
  {
    std::cout << "T is int." << std::endl;
  }

  void MyFunction(typename std::enable_if<!std::is_same<T, int>::value, float &>::type* = 0)
  {
    std::cout << "T is not int." << std::endl;
  }
};</code>

ただし、このコードはコンパイルに失敗し、「'struct std::enable_if' に 'type' という名前の型がありません」というエラーが発生します。

SFINAE の動作

この問題を理解する鍵は、置換失敗はエラーではない (SFINAE) の概念にあります。 Enable_if により、テンプレート引数に基づいた条件付きコンパイルが可能になります。この場合、テンプレート引数 T は、メンバー関数がインスタンス化されるときにすでにわかっています。したがって、インスタンス化時に条件が評価され、対応する関数が選択されます。

コードの修正

これを修正するには、ダミーのテンプレート引数を導入する必要があります。デフォルトは T です。これにより、SFINAE メカニズムが意図したとおりに動作できるようになります。変更されたコードは次のようになります。

<code class="cpp">template<typename T>
struct Point
{
  template<typename U = T>
  typename std::enable_if<std::is_same<U, int>::value>::type
    MyFunction()
  {
    std::cout << "T is int." << std::endl;
  }

  template<typename U = T>
  typename std::enable_if<std::is_same<U, float>::value>::type
    MyFunction()
  {
    std::cout << "T is not int." << std::endl;
  }
};</code>

明示的なメンバー関数の特殊化の防止

HostileFork によって指摘されているように、元のコードではテンプレート引数の明示的な指定が許可されています。メンバー関数の場合、不正確な結果が生じる可能性があります。これを防ぐために、テンプレート引数が提供されているかどうかを確認する static_assert を追加できます。これにより、テンプレート引数 T に基づいて正しいメンバー関数が常に呼び出されることになります。変更されたコードは次のようになります。

<code class="cpp">template<typename T>
struct Point
{
  template<typename... Dummy, typename U = T>
  typename std::enable_if<std::is_same<U, int>::value>::type
    MyFunction()
  {
    static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!");
    std::cout << "T is int." << std::endl;
  }

  template<typename... Dummy, typename U = T>
  typename std::enable_if<std::is_same<U, float>::value>::type
    MyFunction()
  {
    static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!");
    std::cout << "T is not int." << std::endl;
  }
};</code>

以上が「enable_if」を使用してテンプレートパラメータに基づいてメンバー関数を選択する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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