Rumah > pembangunan bahagian belakang > C++ > Bagaimanakah anda boleh mencetak cantik `std::tuple` menggunakan templat variadic?

Bagaimanakah anda boleh mencetak cantik `std::tuple` menggunakan templat variadic?

Susan Sarandon
Lepaskan: 2024-11-07 07:22:03
asal
893 orang telah melayarinya

How can you pretty-print `std::tuple` using variadic templates?

Pretty-Printing of std::tuple Menggunakan Templat Variadic

Sebagai susulan kepada perbincangan sebelumnya tentang bekas STL yang cantik-cetak , kami menyasarkan untuk melanjutkan keupayaan ini untuk memasukkan std::tuple menggunakan templat variadic.

Masalahnya

Untuk std::pair, kami sebelum ini melaksanakan operator tersuai beban berlebihan untuk pencetakan cantik:

std::ostream & operator<<(std::ostream &o, const std::pair<S,T> &p) {
  return o << "(" << p.first << ", " << p.second << ")";
}
Salin selepas log masuk

Matlamatnya adalah untuk mencipta pembinaan yang serupa untuk std::tuple.

Penyelesaian

namespace aux {
// Index sequence utility
template<std::size_t...> struct seq {};
template<std::size_t N, std::size_t... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...> {};
template<> struct gen_seq<0> : seq<> {};

// Recursive printing function using indices
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)...};
}
} // aux::

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 << ")";
}
Salin selepas log masuk

Keluasan Bonus

Untuk meningkatkan keluasan, tambahkan pengkhususan separa untuk pengendalian pembatas:

// 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")" };
Salin selepas log masuk

Sepadukan perubahan ini ke dalam operator<< dan print_tuple:

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;

  aux::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;
}

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)...};
}
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimanakah anda boleh mencetak cantik `std::tuple` menggunakan templat variadic?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan