Heim >Backend-Entwicklung >C++ >Wie drucke ich „std::tuple' in C 11 mithilfe von Variadic-Vorlagen hübsch aus?
Dieser Artikel ist eine Fortsetzung einer früheren Diskussion über Pretty-Printing-STL-Container, für die wir eine elegante und allgemeine Lösung entwickelt haben Diese Aufgabe.
Problemstellung
In dieser Erweiterung wollen wir Pretty-Printing-Funktionen für std::tuple-Objekte unter Verwendung variadicer Vorlagen einbinden, die speziell auf C 11 zugeschnitten sind Inspiriert durch das vorherige Beispiel für std::pair suchen wir eine analoge Konstruktion für Tupel. Das gewünschte Verhalten ist wie folgt:
auto a = std::make_tuple(5, "Hello", -0.1); std::cout << a << std::endl; // prints: (5, "Hello", -0.1)
Darüber hinaus möchten wir den gleichen Grad an Allgemeingültigkeit wie bei der vorherigen Frage einbeziehen, einschließlich der Unterstützung verschiedener Zeichentypen und anpassbarer Paartrennzeichen.
Lösung
Unter Ausnutzung des indizesbasierten Ansatzes können wir eine Lösung mit dem folgenden Codeausschnitt erstellen:
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 << ")"; }
Zur Anpassung von Trennzeichen können wir diese teilweise hinzufügen Spezialisierungen:
// 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")" };
Mit diesen Modifikationen ist der Betreiber<< und print_tuple-Funktionen können aktualisiert werden, um die Trennzeichenanpassung zu integrieren:
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; }
Das obige ist der detaillierte Inhalt vonWie drucke ich „std::tuple' in C 11 mithilfe von Variadic-Vorlagen hübsch aus?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!