Jak wydrukować std :: vector <> :: size_type?
std::vectorma typ członka size_type. Jaki jest jego specyfikator formatu printf?
Zauważ, że size_typeto nie jest identyczne z 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
Odpowiedzi
Jaki jest jego specyfikator formatu printf?
Nikt nie wie. Nie określono, czym std::vector<?>::size_typedokładnie jest, z wyjątkiem tego, że jest to „typ liczby całkowitej bez znaku” int C ++ Container Library, Ogólne wymagania dotyczące kontenerów . Ponieważ printfspecyfikator formatu zależy od typu, wszystko zależy od konkretnej implementacji. Może się również zdarzyć, że nie istnieje printfspecyfikator formatu.
Jak wydrukować std :: vector <> :: size_type?
W krokach:
- Utwórz bibliotekę, aby uzyskać
printfspecyfikator formatowania w zależności od typu. - Skonfiguruj tę bibliotekę dla tego typu.
std::cout::operator<<Zresztą to to samo, co przeciążenie drukowania. Właśnie:
#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));
}
Skromny, praktyczny hack
Wydaje się, że nie ma na to eleganckiego, prostego sposobu, jak sugerują inne odpowiedzi. Co więc robić? Z braku lepszego podejścia, bądźmy pokorni i wróćmy do podstaw:
- Znajdź specyfikatory formatu printf dla największych (pod względem rozmiaru) typów całkowitych ze znakiem i bez znaku, jakie możesz.
- W czasie kompilacji określ podpis wektora
size_typeza pomocąstd::is_signed_t<T>. - W czasie wykonywania sprawdź, czy wartość rozmiaru jest wystarczająco mała, aby pasowała do typu docelowego, w przeciwnym razie po prostu zadeklaruj błąd.
- Rzutuj na
size_typeodpowiedni typ liczby całkowitej. - Możesz teraz użyć wartości rzutowania w wywołaniu printf.
PS - Aby wybrać między specyfikatorami formatu ze znakiem / bez znaku, musisz albo utworzyć ciąg formatu dynamicznie, albo wybrać między dwoma ciągami formatującymi, albo użyć kompilacji warunkowej itp. Zamiast tego możesz po prostu wybrać największy typ ze znakiem i zawsze rzutować w to - za cenę niepowodzenia w przypadku największych rozmiarów, które wymagają tego ostatniego bitu.