Comment imprimer le std :: vector <> :: size_type?
std::vectora un type de membre size_type. Quel est son spécificateur de format printf?
Notez que ce size_typen'est pas identique à size_t.
https://en.cppreference.com/w/cpp/container/vector
https://en.cppreference.com/w/cpp/types/size_t
https://en.cppreference.com/w/cpp/io/c/fprintf
Réponses
Quel est son spécificateur de format printf?
Personne ne sait. Ce n'est pas spécifié ce std::vector<?>::size_typeque c'est exactement, sauf qu'il s'agit d'un "type entier non signé" int C ++ Container Library, General container requirements . Étant donné que le printfspécificateur de format dépend du type, tout dépend d'une implémentation particulière. Il est également possible qu'il n'existe pas de printfspécificateur de format.
Comment printf std :: vector <> :: size_type?
Par étapes:
- Créez une bibliothèque pour obtenir un
printfspécificateur de mise en forme en fonction du type. - Modélisez cette bibliothèque sur ce type.
C'est exactement la même chose que les std::cout::operator<<surcharges pour l'impression de toute façon. Juste:
#include <cstdlib>
#include <string>
#include <cstdio>
#include <vector>
template<typename T> constexpr const char *get_printf_formatting_spec() noexcept;
template<> constexpr const char *get_printf_formatting_spec<std::size_t>() noexcept {
return "zu";
}
template<> constexpr const char *get_printf_formatting_spec<unsigned long long>() noexcept {
return "llu";
}
/// etc.
int main() {
const auto fmt = std::string() +
"%" +
get_printf_formatting_spec<std::vector<int>::size_type>() +
"\n";
std::printf(fmt.c_str(), static_cast<std::vector<int>::size_type>(1));
}
Un humble hack pratique
Il ne semble pas y avoir de moyen élégant et simple de le faire, comme le suggèrent d'autres réponses. Que faire alors? Faute d'une meilleure approche, soyons humbles et revenons à l'essentiel:
- Recherchez des spécificateurs de format printf pour les types d'entiers signés et non signés les plus grands (en termes de taille) que vous pouvez.
- Au moment de la compilation, déterminez la signature du vecteur à l'
size_typeaide destd::is_signed_t<T>. - Au moment de l'exécution, vérifiez que la valeur de la taille est suffisamment petite pour s'adapter au type de cible, sinon déclarez simplement l'échec.
- Convertissez le
size_typedans le type entier approprié. - Vous pouvez maintenant utiliser la valeur de conversion dans un appel printf.
PS - Pour choisir entre les spécificateurs de format signés / non signés, vous devrez soit construire la chaîne de format de manière dynamique, soit choisir entre deux chaînes de format, ou utiliser la compilation conditionnelle, etc. dans cela - au prix de l'échec pour les plus grandes tailles qui ont besoin de ce dernier bit.