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

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

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-10 00:21:02812parcourir

How can you pretty-print a `std::tuple` using variadic templates in C  11?

Pretty-Printing std::tuple

Dans une question précédente sur l'embellissement des conteneurs STL, nous avons développé avec succès une solution complète et gracieuse. Cette étape suivante plonge dans le domaine de l'impression std::tuple à l'aide de modèles variadiques (exclusivement C 11).

Arrière-plan

Pour std::pair, le la syntaxe est simple :

std::ostream & operator<<(std::ostream &, const std::pair<S, T> &);

Construction analogique pour Tuple

Le casse-tête réside dans la définition d'une construction analogue pour imprimer un tuple. Nous visons ce comportement :

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

Solution

La réponse réside dans l'exploitation des indices :

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

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

Bonus : Délimiteurs

Pour plus de flexibilité, nous proposons des 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")" };

Conclusion

Avec les modifications ci-dessus, joli-printing std::tuple peut être personnalisé pour s'adapter à différents jeux de caractères et préférences de délimiteur, offrant un solution élégante et polyvalente.

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!

Déclaration:
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