วิธี printf std :: vector <> :: size_type?

Oct 11 2020

std::vectorsize_typeมีประเภทสมาชิก ตัวระบุรูปแบบ printf คืออะไร?

โปรดทราบว่าไม่เหมือนกันsize_typesize_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

คำตอบ

4 KamilCuk Oct 11 2020 at 20:55

ตัวระบุรูปแบบ printf คืออะไร?

ไม่มีใครรู้ว่า. มันไม่ได้ระบุสิ่งstd::vector<?>::size_typeที่แน่นอนคือยกเว้นว่ามันเป็น "ชนิดจำนวนเต็มไม่ได้ลงนาม" int c ++ คอนเทนเนอร์ห้องสมุดความต้องการภาชนะทั่วไป เนื่องจากตัวprintfระบุรูปแบบขึ้นอยู่กับประเภททั้งหมดขึ้นอยู่กับการนำไปใช้งานเฉพาะ อาจเป็นไปได้ว่าไม่มีตัวprintfระบุรูปแบบ

วิธี printf std :: vector <> :: size_type?

ในขั้นตอน:

  1. สร้างไลบรารีเพื่อรับตัวprintfระบุการจัดรูปแบบขึ้นอยู่กับประเภท
  2. เทมเพลตไลบรารีในประเภทนั้น

มันก็เหมือนกับการstd::cout::operator<<โอเวอร์โหลดสำหรับการพิมพ์อยู่ดี แค่:

#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

แฮ็คเชิงปฏิบัติที่ต่ำต้อย

ดูเหมือนจะไม่มีวิธีที่หรูหราและตรงไปตรงมาในการทำเช่นนี้อย่างที่คำตอบอื่น ๆ แนะนำ แล้วจะทำอย่างไร? หากไม่มีแนวทางที่ดีกว่าเรามาถ่อมตัวและกลับไปที่พื้นฐาน:

  1. ค้นหาตัวระบุรูปแบบ printf สำหรับประเภทจำนวนเต็มที่ลงนามและไม่ได้ลงชื่อที่ใหญ่ที่สุดที่คุณสามารถทำได้
  2. ที่รวบรวมเวลากำหนด signedness ของเวกเตอร์โดยใช้size_typestd::is_signed_t<T>
  3. ในขณะดำเนินการตรวจสอบว่าค่าขนาดเล็กพอที่จะใส่ลงในประเภทเป้าหมายมิฉะนั้นเพียงแค่ประกาศความล้มเหลว
  4. แคสต์เป็นsize_typeประเภทจำนวนเต็มที่เหมาะสม
  5. ตอนนี้คุณสามารถใช้ค่าร่ายในการเรียก printf ได้แล้ว

PS - ในการเลือกระหว่างตัวระบุรูปแบบที่ลงนาม / ไม่ได้ลงชื่อคุณจะต้องสร้างสตริงรูปแบบแบบไดนามิกหรือเลือกระหว่างสตริงรูปแบบสองรูปแบบหรือใช้การคอมไพล์ตามเงื่อนไขเป็นต้น แต่คุณสามารถเลือกประเภทที่เซ็นชื่อใหญ่ที่สุดและแคสต์ได้เสมอ ในนั้น - ในราคาที่ล้มเหลวสำหรับขนาดที่ใหญ่ที่สุดซึ่งต้องการบิตสุดท้ายนั้น