Heim  >  Artikel  >  Backend-Entwicklung  >  Wie können Sie „std::tuple“ mit verschiedenen Vorlagen und benutzerdefinierten Trennzeichen hübsch drucken?

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

Susan Sarandon
Susan SarandonOriginal
2024-11-08 07:27:01988Durchsuche

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

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

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

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

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)

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!

Stellungnahme:
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