Wie drucke ich std::vector<>::size_type?

Oct 11 2020

std::vectorhat einen Mitgliedstyp size_type. Was ist sein printf-Formatbezeichner?

Beachten Sie, dass dies size_typenicht mit identisch ist 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

Antworten

4 KamilCuk Oct 11 2020 at 20:55

Was ist sein printf-Formatbezeichner?

Niemand weiß. Es wird nicht std::vector<?>::size_typegenau angegeben, was genau ist, außer dass es sich um einen "unsigned Integer-Typ" int C++ Container Library, Allgemeine Containeranforderungen handelt . Da der printfFormatbezeichner vom Typ abhängt, hängt alles von der jeweiligen Implementierung ab. Es kann auch möglich sein, dass kein printfFormatbezeichner vorhanden ist.

Wie drucke ich std::vector<>::size_type?

In Schritten:

  1. Erstellen Sie eine Bibliothek, um printfje nach Typ einen Formatierungsbezeichner zu erhalten .
  2. Erstellen Sie eine Vorlage für diese Bibliothek für diesen Typ.

Es ist std::cout::operator<<sowieso das Gleiche, was Überladungen beim Drucken tun. Gerade:

#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));
}
1 einpoklum Oct 12 2020 at 15:03

Ein bescheidener praktischer Hack

Es scheint keinen eleganten, unkomplizierten Weg zu geben, wie andere Antworten nahelegen. Was also tun? Lassen Sie uns in Ermangelung eines besseren Ansatzes bescheiden sein und zu den Grundlagen zurückkehren:

  1. Suchen Sie nach printf-Formatbezeichnern für die größten (größenmäßig) vorzeichenbehafteten und vorzeichenlosen Ganzzahltypen, die Sie können.
  2. Bestimmen Sie zur Kompilierzeit das Vorzeichen des Vektors size_typemit std::is_signed_t<T>.
  3. Überprüfen Sie zur Laufzeit, ob der Größenwert klein genug ist, um in den Zieltyp zu passen, andernfalls deklarieren Sie einfach einen Fehler.
  4. Wandeln Sie die size_typein den entsprechenden Integer-Typ um.
  5. Sie können den Cast-Wert jetzt in einem printf-Aufruf verwenden.

PS - Um zwischen den Formatbezeichnern mit/ohne Vorzeichen zu wählen, müssen Sie entweder die Formatzeichenfolge dynamisch erstellen oder zwischen zwei Formatzeichenfolgen wählen oder eine bedingte Kompilierung verwenden usw. Stattdessen können Sie einfach den größten vorzeichenbehafteten Typ wählen und immer umwandeln in diese - um den Preis für die größten Größen zu scheitern , die das letzte Bit benötigen.