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

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

Mary-Kate Olsen
リリース: 2024-12-13 07:27:10
オリジナル
1043 人が閲覧しました

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

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート