汎用コンテナー印刷の std::is_same: 失敗する理由と解決策
汎用関数を作成しようとしたときに問題が発生しましたスタックコンテナとキューコンテナの両方を印刷します。この関数には当初、コンテナーのタイプ (スタックまたはキュー) を決定し、それに応じてその要素にアクセスするための条件ステートメントが含まれていました。ただし、このアプローチでは、2 つのコンテナ タイプ間のメンバー関数の違いにより、コンパイル エラーが発生しました。
問題の理解:
コンパイル エラーは、次の事実に起因します。 if-else ステートメントのブランチがスタック タイプのfront() とキュー タイプのtop() にアクセスしようとしているということです。これらのアクセサーはそれぞれの型では使用できないため、コンパイラーからエラーが発生します。 C には強力な型指定があり、サポートする対応するメンバー関数を特定の型に提供する必要があります。
問題の解決:
この問題を解決するには、次のことが必要です。これは、特定のメンバー関数へのアクセスを提供しながら、コンテナーの種類を区別できるソリューションです。考えられる解決策は 2 つあります。
1.アクセサーによる部分的な特殊化:
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); // call the accessor function std::cout << elem << '\n'; cont.pop(); } }
2. C 17 を使用した if constexpr:
開発環境が 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>
どちらのソリューションでも、スタック コンテナとキュー コンテナの両方を出力できる汎用関数を作成でき、DFS や BFS などの検索アルゴリズム間でコードを効果的に共有できます。
以上が汎用コンテナーの印刷時に `std::is_same` が失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。