Home >Backend Development >C++ >How can you pretty-print `std::tuple` using variadic templates?
Pretty-Printing of std::tuple Using Variadic Templates
In a follow-up to a previous discussion on pretty-printing STL containers, we aim to extend this capability to include std::tuple using variadic templates.
The Problem
For std::pair, we previously implemented a custom operator overload for pretty-printing:
std::ostream & operator &p) { return o <p>The goal is to create a similar construction for std::tuple.</p><p><strong>The Solution</strong></p><pre class="brush:php;toolbar:false">namespace aux { // Index sequence utility template<:size_t...> struct seq {}; template<:size_t n std::size_t... is> struct gen_seq : gen_seq<n-1 n-1 is...> {}; template struct gen_seq : seq {}; // Recursive printing function using indices template<class ch class tr tuple std::size_t... is> void print_tuple(std::basic_ostream<ch>& os, Tuple const& t, seq<is...>) { using swallow = int[]; (void)swallow{0, (void(os (t)), 0)...}; } } // aux:: template<class ch class tr class... args> auto operator& os, std::tuple<args...> const& t) -> std::basic_ostream<ch tr>& { os ()); return os <p><strong>Bonus Generality</strong></p> <p>To enhance generality, add partial specializations for delimiter handling:</p> <pre class="brush:php;toolbar:false">// Delimiters for tuple template<class... args> struct delimiters<:tuple>, char> { static const delimiters_values<char> values; }; template<class... args> const delimiters_values<char> delimiters<:tuple>, char>::values = { "(", ", ", ")" }; template<class... args> struct delimiters<:tuple>, wchar_t> { static const delimiters_values<wchar_t> values; }; template<class... args> const delimiters_values<wchar_t> delimiters<:tuple>, wchar_t>::values = { L"(", L", ", L")" };</:tuple></wchar_t></class...></wchar_t></:tuple></class...></:tuple></char></class...></char></:tuple></class...>
Integrate these changes into operator
template<class ch class tr class... args> auto operator& 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 ::values.prefix; aux::print_tuple(os, t, aux::gen_seq<sizeof...>()); if(delimiters<tuple_t ch>::values.postfix != 0) os ::values.postfix; return os; } template<class ch class tr 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 (t)), 0)...}; }</tuple></is...></ch></class></tuple_t></sizeof...></tuple_t></args...></ch></args...></class>
The above is the detailed content of How can you pretty-print `std::tuple` using variadic templates?. For more information, please follow other related articles on the PHP Chinese website!