可変引数テンプレートを使用して C 11 で `std::tuple` をきれいに印刷する方法

Barbara Streisand
リリース: 2024-11-07 17:44:03
オリジナル
764 人が閲覧しました

How to Pretty-Print `std::tuple` in C  11 Using Variadic Templates?

きれいに印刷する std::tuple

この記事は、きれいに印刷する STL コンテナに関する以前の議論の続きであり、そこでは、このタスク。

問題ステートメント

この拡張機能では、特に C 11 向けに調整された、可変個引数テンプレートを使用した std::tuple オブジェクトの整形機能を含めることを目的としています。前述の std::pair の例からインスピレーションを得て、タプルにも同様の構造を求めます。望ましい動作は次のとおりです。

auto a = std::make_tuple(5, "Hello", -0.1);
std::cout << a << std::endl; // prints: (5, "Hello", -0.1)
ログイン後にコピー

さらに、さまざまな文字タイプやカスタマイズ可能なペア区切り文字のサポートなど、前の質問と同じレベルの汎用性を組み込むことを目指しています。

ソリューション

インデックスベースのアプローチを活用すると、次のコード スニペットを使用してソリューションを構築できます。

namespace aux{
template<std::size_t... Is> struct seq{};

template<std::size_t N, std::size_t... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};

template<std::size_t... Is>
struct gen_seq<0, Is...> : seq<Is...>{};

template<class Ch, class Tr, class Tuple, std::size_t... Is>
void print_tuple(std::basic_ostream<Ch,Tr>& os, Tuple const& t, seq<Is...>)
{
  using swallow = int[];
  (void)swallow{0, (void(
    os << (Is == 0? "" : ", ") << std::get<Is>(t)
  ), 0)...};
}
}

template<class Ch, class Tr, class... Args>
auto operator<<(std::basic_ostream<Ch, Tr>& os, std::tuple<Args...> const& t)
    -> std::basic_ostream<Ch, Tr>&
{
  os << "(";
  aux::print_tuple(os, t, aux::gen_seq<sizeof...(Args)>()
);
  return os << ")";
}
ログイン後にコピー

区切り文字のカスタマイズについては、次の部分的なコードを追加できます。特殊化:

// Delimiters for tuple
template<class... Args>
struct delimiters<std::tuple<Args...>, char> {
  static const delimiters_values<char> values;
};

template<class... Args>
const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values =
    { "(", ", ", ")" };

template<class... Args>
struct delimiters<std::tuple<Args...>, wchar_t> {
  static const delimiters_values<wchar_t> values;
};

template<class... Args>
const delimiters_values<wchar_t> delimiters<
    std::tuple<Args...>, wchar_t
>::values = { L"(", L", ", L")" };
ログイン後にコピー

これらの変更により、演算子<< print_tuple 関数は、区切り文字のカスタマイズを組み込むように更新できます:

template<class Ch, class Tr, class Tuple, std::size_t... Is>
void print_tuple(std::basic_ostream<Ch, Tr>& os, Tuple const& t, seq<Is...>)
{
  using swallow = int[];
  char const* delim = delimiters<Tuple, Ch>::values.delimiter;
  if(!delim) delim = "";
  (void)swallow{0, (void(
    os << (Is == 0? "" : delim) << std::get<Is>(t)
  ), 0)...};
}
ログイン後にコピー
template<class Ch, class Tr, class... Args>
auto operator<<(std::basic_ostream<Ch, Tr>& os, std::tuple<Args...> const& t)
    -> std::basic_ostream<Ch, Tr>&
{
  typedef std::tuple<Args...> tuple_t;
  if(delimiters<tuple_t, Ch>::values.prefix != 0)
    os << delimiters<tuple_t,char>::values.prefix;

  print_tuple(os, t, aux::gen_seq<sizeof...(Args)>()
);

  if(delimiters<tuple_t, Ch>::values.postfix != 0)
    os << delimiters<tuple_t,char>::values.postfix;

  return os;
}
ログイン後にコピー

以上が可変引数テンプレートを使用して C 11 で `std::tuple` をきれいに印刷する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!