Heim > Backend-Entwicklung > C++ > Hauptteil

Wie können Sie „std::tuple' mit verschiedenen Vorlagen und benutzerdefinierten Trennzeichen hübsch drucken?

Susan Sarandon
Freigeben: 2024-11-08 07:27:01
Original
1059 Leute haben es durchsucht

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

Pretty-Printing std::tuple

In einer früheren Frage haben wir eine elegante Lösung für Pretty-Printing von STL-Containern erstellt. Kommen wir nun zum Pretty-Printing für std::tuple unter Verwendung verschiedener Vorlagen.

Für std::pair können wir mit benutzerdefinierten Operatoren drucken:

std::ostream &operator<<(std::ostream &o, const std::pair<S,T> &p)
{
  return o << "(" << p.first << ", " << p.second << ")";
}
Nach dem Login kopieren

Um dies auf Tupel zu verallgemeinern, können wir das Entpacken von Vorlagenargumenten und nutzen Generierung von Indizes:

namespace aux{
template<std::size_t... Is> struct seq{}; // dummy helper type

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...>){ // overload to print tuples
  using swallow = int[]; // silence unused warning
  (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)>()); // call template overload with index helper to print
  return os << ")";
}
Nach dem Login kopieren

Um benutzerdefinierte Trennzeichen hinzuzufügen (z. B. für char und wchar_t), können wir Teilspezialisierungen verwenden:

// 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")" };
Nach dem Login kopieren

Und passen Sie den Operator<< und print_tuple entsprechend:

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

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...>){ 
  char const* delim = delimiters<Tuple, Ch>::values.delimiter;
  if(!delim) delim = "";
  (void)swallow{0, (void(os << (Is == 0? "" : delim) << std::get<Is>(t)), 0)...};
}
Nach dem Login kopieren

Jetzt ist das Drucken von std::tuple mit benutzerdefinierten Trennzeichen so einfach wie:

auto a = std::make_tuple(5, "Hello", -0.1);
std::cout << a << std::endl; // prints: (5, "Hello", -0.1)
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie können Sie „std::tuple' mit verschiedenen Vorlagen und benutzerdefinierten Trennzeichen hübsch drucken?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage