さまざまな enable_if 条件を使用したメンバー関数の選択
C では、enable_if メタ関数を使用して、コンパイルに基づいてコードを選択的に有効または無効にすることができます。 -時間条件。この手法は、さまざまなタイプの引数を処理したり、テンプレート パラメーターに応じてさまざまなアクションを実行したりするメンバー関数のオーバーロードを提供するためによく使用されます。
enable_if を使用してクラス テンプレート パラメーターに基づいてメンバー関数を選択しようとする場合、重要です。これは、enable_if が、オーバーロード解決セットから削除されるエラーを引き起こすテンプレート引数の置換を引き起こすことによって機能することを理解するためです。
問題:
提供されたコードでは、 Enable_if 条件はメンバー関数に直接適用されますが、テンプレート引数 T はこれらの関数をインスタンス化するときにすでに既知であるため、このアプローチでは望ましい効果は得られません。
<code class="cpp">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>
解決策:
この問題を解決するには、デフォルトで 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 を使用して、明示的な引数が指定されていないことを確認します:
<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>
以上がC でenable_if を使用してクラス テンプレート パラメーターに基づいてメンバー関数を選択する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。