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 サイトの他の関連記事を参照してください。