ホームページ >バックエンド開発 >C++ >SFINAE が戻り値の型では失敗するのに、テンプレート パラメータでは成功するのはなぜですか?

SFINAE が戻り値の型では失敗するのに、テンプレート パラメータでは成功するのはなぜですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-13 07:27:10981ブラウズ

Why Does SFINAE Fail in Return Types but Succeed with Template Parameters?

戻り値の型とテンプレート パラメーターの 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 サイトの他の関連記事を参照してください。

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