Heim >Backend-Entwicklung >C++ >Wie drucke ich „std::tuple' in C 11 mithilfe von Variadic-Vorlagen hübsch aus?

Wie drucke ich „std::tuple' in C 11 mithilfe von Variadic-Vorlagen hübsch aus?

Barbara Streisand
Barbara StreisandOriginal
2024-11-07 17:44:03827Durchsuche

How to Pretty-Print `std::tuple` in C  11 Using Variadic Templates?

Pretty-Printing std::tuple

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!

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