Bagaimana cara printf std :: vector <> :: size_type?

Oct 11 2020

std::vectormemiliki tipe anggota size_type. Apa penentu format printf-nya?

Perhatikan bahwa size_typetidak identik dengan 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

Jawaban

4 KamilCuk Oct 11 2020 at 20:55

Apa penentu format printf-nya?

Tidak ada yang tahu. Ini tidak ditentukan apa std::vector<?>::size_typesebenarnya, kecuali bahwa itu adalah "tipe integer tak bertanda tangan" int C ++ Container Library, Persyaratan penampung umum . Karena printfpenentu format bergantung pada jenisnya, semuanya bergantung pada implementasi tertentu. Mungkin juga tidak ada penentu printfformat.

Bagaimana cara printf std :: vector <> :: size_type?

Dalam langkah-langkah:

  1. Buat pustaka untuk mendapatkan printfpenentu pemformatan tergantung pada tipenya.
  2. Templat perpustakaan itu pada tipe itu.

Ini sama saja dengan std::cout::operator<<melakukan kelebihan beban untuk pencetakan. Hanya:

#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

Peretasan praktis yang sederhana

Sepertinya tidak ada cara yang elegan dan langsung untuk melakukan ini, seperti yang disarankan oleh jawaban lain. Lalu apa yang harus dilakukan? Karena kurangnya pendekatan yang lebih baik, mari kita rendah hati dan kembali ke dasar:

  1. Temukan penentu format printf untuk tipe bilangan bulat bertanda tangan dan tak bertanda tangan dan tak bertanda tangan terbesar (berdasarkan ukuran) yang Anda bisa.
  2. Pada waktu kompilasi, tentukan tanda tangan vektor size_typemenggunakan std::is_signed_t<T>.
  3. Pada waktu proses, periksa apakah nilai ukuran cukup kecil untuk disesuaikan dengan jenis target, jika tidak, cukup nyatakan kegagalan.
  4. Transmisikan size_typeke jenis bilangan bulat yang sesuai.
  5. Sekarang Anda dapat menggunakan nilai cast dalam panggilan printf.

PS - Untuk memilih antara penentu format bertanda tangan / tidak bertanda tangan, Anda perlu membuat string format secara dinamis, atau memilih antara dua string format, atau menggunakan kompilasi bersyarat, dll. Sebagai gantinya, Anda dapat memilih jenis bertanda tangan terbesar dan selalu mentransmisikan ke dalam itu - dengan harga gagal untuk ukuran terbesar yang membutuhkan bit terakhir.