Làm thế nào để printf std :: vector <> :: size_type?

Oct 11 2020

std::vectorcó một loại thành viên size_type. Định dạng printf của nó là gì?

Lưu ý rằng size_typekhông giống với 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

Trả lời

4 KamilCuk Oct 11 2020 at 20:55

Định dạng printf của nó là gì?

Không ai biết. Nó không được chỉ định std::vector<?>::size_typechính xác là gì , ngoại trừ nó là "kiểu số nguyên không dấu" int C ++ Container Library, Yêu cầu chung về vùng chứa . Bởi vì printfđịnh dạng định dạng phụ thuộc vào loại, tất cả phụ thuộc vào việc triển khai cụ thể. Cũng có thể không tồn tại bộ printfđịnh dạng.

Làm thế nào để printf std :: vector <> :: size_type?

Trong các bước:

  1. Tạo một thư viện để nhận thông số printfđịnh dạng tùy thuộc vào loại.
  2. Mẫu thư viện đó trên loại đó.

Dù sao thì nó cũng giống như std::cout::operator<<quá tải đang làm cho việc in ấn. Chỉ:

#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

Một hack thực tế khiêm tốn

Dường như không có cách nào thanh lịch và đơn giản để làm điều này, như các câu trả lời khác gợi ý. Vậy thì phải làm gì? Nếu thiếu một cách tiếp cận tốt hơn, hãy khiêm tốn và quay lại những điều cơ bản:

  1. Tìm các chỉ định định dạng printf cho các kiểu số nguyên có dấu và không dấu lớn nhất (phù hợp với kích thước) mà bạn có thể.
  2. Tại thời điểm biên dịch, hãy xác định tính có dấu của vectơ size_typebằng cách sử dụng std::is_signed_t<T>.
  3. Tại thời điểm chạy, hãy kiểm tra xem giá trị kích thước có đủ nhỏ để vừa với loại đích hay không, nếu không thì chỉ cần thông báo lỗi.
  4. Truyền size_typetới kiểu số nguyên thích hợp.
  5. Bây giờ bạn có thể sử dụng giá trị ép kiểu trong lệnh gọi printf.

Tái bút - Để chọn giữa các chỉ định định dạng có dấu / không dấu, bạn sẽ cần phải xây dựng chuỗi định dạng động, hoặc chọn giữa hai chuỗi định dạng hoặc sử dụng biên dịch có điều kiện, v.v. Thay vào đó, bạn chỉ có thể chọn loại có dấu lớn nhất và luôn ép kiểu vào đó - với cái giá là thất bại đối với các kích thước lớn nhất cần bit cuối cùng đó.