Maison > développement back-end > C++ > Comment joliment imprimer `std::tuple` en C 11 à l'aide de modèles variadiques ?

Comment joliment imprimer `std::tuple` en C 11 à l'aide de modèles variadiques ?

Barbara Streisand
Libérer: 2024-11-07 17:44:03
original
861 Les gens l'ont consulté

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

Std::tuple à jolie impression

Cet article est la suite d'une discussion précédente sur les conteneurs STL à jolie impression, où nous avons développé une solution élégante et générale pour cette tâche.

Énoncé du problème

Dans cette extension, nous visons à inclure une fonctionnalité d'impression jolie pour les objets std::tuple à l'aide de modèles variadiques, spécifiquement adaptés à C 11. . Inspirés de l'exemple précédent pour std::pair, nous recherchons une construction analogue pour les tuples. Le comportement souhaité est le suivant :

auto a = std::make_tuple(5, "Hello", -0.1);
std::cout << a << std::endl; // prints: (5, "Hello", -0.1)
Copier après la connexion

De plus, nous visons à incorporer le même niveau de généralité que la question précédente, y compris la prise en charge de différents types de caractères et de délimiteurs de paires personnalisables.

Solution

En exploitant l'approche basée sur les indices, nous pouvons construire une solution en utilisant l'extrait de code suivant :

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 << ")";
}
Copier après la connexion

Pour la personnalisation des délimiteurs, nous pouvons ajouter ces partiels spécialisations :

// 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")" };
Copier après la connexion

Avec ces modifications, l'opérateur<< et les fonctions print_tuple peuvent être mises à jour pour intégrer la personnalisation du délimiteur :

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)...};
}
Copier après la connexion
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;
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal