Rumah > Artikel > pembangunan bahagian belakang > Bagaimana untuk Mencetak Cantik `std::tuple` dalam C 11 Menggunakan Templat Variadic?
Artikel ini adalah kesinambungan perbincangan sebelumnya tentang bekas STL yang cantik-cetak, di mana kami membangunkan penyelesaian yang elegan dan umum untuk tugasan ini.
Pernyataan Masalah
Dalam sambungan ini, kami menyasarkan untuk memasukkan fungsi pencetakan cantik untuk objek std::tuple menggunakan templat variadic, yang disesuaikan khusus untuk C 11 . Diilhamkan oleh contoh sebelumnya untuk std::pair, kami mencari binaan analog untuk tupel. Tingkah laku yang diingini adalah seperti berikut:
auto a = std::make_tuple(5, "Hello", -0.1); std::cout << a << std::endl; // prints: (5, "Hello", -0.1)
Selain itu, kami menyasarkan untuk menggabungkan tahap umum yang sama seperti soalan sebelumnya, termasuk sokongan untuk jenis watak yang berbeza dan pembatas pasangan yang boleh disesuaikan.
Penyelesaian
Mengeksploitasi pendekatan berasaskan indeks, kami boleh membina penyelesaian menggunakan coretan kod berikut:
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 << ")"; }
Untuk penyesuaian pembatas, kami boleh menambah separa ini pengkhususan:
// 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")" };
Dengan pengubahsuaian ini, pengendali<< dan fungsi print_tuple boleh dikemas kini untuk menggabungkan penyesuaian pembatas:
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; }
Atas ialah kandungan terperinci Bagaimana untuk Mencetak Cantik `std::tuple` dalam C 11 Menggunakan Templat Variadic?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!