ホームページ > バックエンド開発 > C++ > C の SFINAE : 条件付きテンプレートの特殊化のための戻り値の型とパラメータの型?

C の SFINAE : 条件付きテンプレートの特殊化のための戻り値の型とパラメータの型?

Mary-Kate Olsen
リリース: 2024-12-13 02:33:13
オリジナル
679 人が閲覧しました

SFINAE in C  : Return Type vs. Parameter Type for Conditional Template Specialization?

テンプレートの戻り値の型とパラメーターの SFINAE

問題の説明

C では、SFINAE (置換失敗はエラーではありません) を次の目的で使用できます。タイプの特性に基づいてテンプレートの特殊化を条件付きで有効または無効にします。ただし、テンプレートの戻り値の型とテンプレート パラメーターで SFINAE が異なる方法で適用される場合に、一般的な問題が発生します。

次の main 関数を考えてみましょう:

int main()
{
    foo(5);
    foo(3.4);
}
ログイン後にコピー

テンプレート パラメーターで SFINAE を使用した実装の誤り

以下に示すように、SFINAE がテンプレート パラメーターに配置されると、次のようにコンパイルに失敗します。エラー:

template<typename T,
         typename = typename std::enable_if<std::is_integral<T>::value>::type>
auto foo(T) -> void
{
    std::cout << "I'm an integrer!\n";
}

template<typename T,
         typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
auto foo(T) -> void
{
    std::cout << "I'm a floating point number!\n";
}
ログイン後にコピー

戻り値の型で SFINAE を使用した正しい実装

ただし、この実装は正しく動作します:

template<typename T>
auto foo(T) -> typename std::enable_if<std::is_integral<T>::value>::type
{
    std::cout << "I'm an integrer!\n";
}

template<typename T>
auto foo(T) -> typename std::enable_if<std::is_floating_point<T>::value>::type
{
    std::cout << "I'm a floating point number!\n";
}
ログイン後にコピー

説明

違い問題は、関数テンプレートのオーバーロードが C 標準 (14.5.6.1) で定義されている方法にあります。オーバーロードされたテンプレートは、同じ関数名、同じ数のパラメータ、同じパラメータ タイプを持つ場合、同等です。ただし、この比較ではデフォルトのテンプレート引数は考慮されません。

欠陥のある実装では、SFINAE 条件がデフォルトのテンプレート引数として含まれており、その結果、2 つの同一の関数テンプレートが 2 回定義されます。これにより、コンパイル エラーが発生します。

正しい実装では、SFINAE 条件はテンプレートの戻り値の型の一部として使用されます。これにはテンプレート パラメーターを参照する式が含まれるため、2 つの関数は異なるシグネチャを持ち、SFINAE が意図したとおりに機能できるようになります。

以上がC の SFINAE : 条件付きテンプレートの特殊化のための戻り値の型とパラメータの型?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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