戻り値の型とテンプレート パラメーターの SFINAE
整数と浮動小数点数を区別する関数テンプレート foo があるとします。
template<typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> auto foo(T) -> void; template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type> auto foo(T) -> void;
ただし、このコードは double で呼び出すとエラーで失敗します。 value:
foo(3.4); // Error: no matching function for call to 'foo(double)'
このアプローチはなぜ失敗しますか?
この場合、SFINAE を使用して foo の戻り値の型を条件付きで定義します。ただし、これは、デフォルトのテンプレート引数を考慮しない関数テンプレートのオーバーロードのルールに違反します。その結果、コンパイラは両方の foo テンプレートを同じシグネチャを持つ同じ関数として扱います。
テンプレート パラメータを参照する式を使用した代替アプローチ
この問題を解決するには、次の方法を使用できます。戻り値の型でテンプレート パラメーターを参照する式を使用します:
template<typename T> auto foo(T) -> typename std::enable_if<std::is_integral<T>::value>::type; template<typename T> auto foo(T) -> typename std::enable_if<std::is_floating_point<T>::value>::type;
この変更により、式はstd::enable_if は関数シグネチャの一部となり、SFINAE が 2 つの foo テンプレートを区別できるようになります。
したがって、foo の 2 番目のバージョンは正しく動作しますが、最初のバージョンではエラーが発生します。
以上がSFINAE が戻り値の型では失敗するのに、テンプレート パラメータでは成功するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。