ホームページ  >  記事  >  バックエンド開発  >  印刷スタックとキューの汎用関数が失敗するのはなぜですか?また、それを修正するにはどうすればよいですか?

印刷スタックとキューの汎用関数が失敗するのはなぜですか?また、それを修正するにはどうすればよいですか?

DDD
DDDオリジナル
2024-11-01 22:17:02939ブラウズ

Why Does My Generic Function for Print Stacks and Queues Fail, and How Can I Fix It?

関数が失敗する理由と問題の解決方法

提供されたコードは、スタックとキューの両方を出力できる汎用関数の作成を試みます。ただし、基本的な問題により失敗します。if-else ステートメントの両方のブランチがコンパイル可能でなければなりません。この場合は、そうではありません。

このエラーは、特に、top() メンバー関数はスタックでのみ使用可能であるのに対し、front() メンバー関数はキューでのみ使用可能であるために発生します。コンパイラーは、同じコンテナー タイプの両方のブランチをコンパイルしようとすると、どのメンバー関数を使用するかを決定できないため、問題にフラグを立てます。

この問題に対する 1 つの解決策は、部分特殊化を使用することです。部分特殊化を使用すると、特定の型またはクラスに対してテンプレートのさまざまな実装を定義できます。この場合、スタックとキューの部分特殊化を定義して、各実装に適切なメンバー関数があることを確認できます。

<code class="cpp">template <typename Cont>
struct element_accessor;

template <typename T>
struct element_accessor<std::stack<T>> {
    const T& operator()(const std::stack<T>& s) const { return s.top(); }
};

template <typename T>
struct element_accessor<std::queue<T>> {
    const T& operator()(const std::queue<T>& q) const { return q.front(); }
};

template<typename Cont>
void print_container(Cont& cont){
    while(!cont.empty()){
        auto elem = element_accessor<Cont>{}(cont);
        std::cout << elem << '\n';
        cont.pop();
    }
}

このソリューションでは、クラス element_accessor を使用して、各コンテナー タイプの適切なメンバー関数にアクセスします。スタックとキューに部分的な特殊化を提供することで、それぞれの場合に正しいコードがコンパイルされるようになります。

C 17 以降で利用可能な別の解決策は、if constexpr:

<code class="cpp">template<template<class> typename Cont, typename T>
void print_container(Cont<T>& cont){
    while(!cont.empty()){
        if constexpr (std::is_same_v<Cont<T>, std::stack<T>>) 
            std::cout << cont.top() << '\n';
        else if constexpr (std::is_same_v<Cont<T>, std::queue<T>>) 
            std::cout << cont.front() << '\n';
        cont.pop();
    }
}</code>
このソリューションは constexpr 条件式を利用して、コンテナーの種類に基づいて正しいコードを選択します。コンパイル時に Cont の型をチェックすることで、各コンテナーに対して正しいメンバー関数が呼び出されることを確認できます。

以上が印刷スタックとキューの汎用関数が失敗するのはなぜですか?また、それを修正するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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