วิธี printf std :: vector <> :: size_type?
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
คำตอบ
ตัวระบุรูปแบบ printf คืออะไร?
ไม่มีใครรู้ว่า. มันไม่ได้ระบุสิ่งstd::vector<?>::size_typeที่แน่นอนคือยกเว้นว่ามันเป็น "ชนิดจำนวนเต็มไม่ได้ลงนาม" int c ++ คอนเทนเนอร์ห้องสมุดความต้องการภาชนะทั่วไป เนื่องจากตัวprintfระบุรูปแบบขึ้นอยู่กับประเภททั้งหมดขึ้นอยู่กับการนำไปใช้งานเฉพาะ อาจเป็นไปได้ว่าไม่มีตัวprintfระบุรูปแบบ
วิธี printf std :: vector <> :: size_type?
ในขั้นตอน:
- สร้างไลบรารีเพื่อรับตัว
printfระบุการจัดรูปแบบขึ้นอยู่กับประเภท - เทมเพลตไลบรารีในประเภทนั้น
มันก็เหมือนกับการ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));
}
แฮ็คเชิงปฏิบัติที่ต่ำต้อย
ดูเหมือนจะไม่มีวิธีที่หรูหราและตรงไปตรงมาในการทำเช่นนี้อย่างที่คำตอบอื่น ๆ แนะนำ แล้วจะทำอย่างไร? หากไม่มีแนวทางที่ดีกว่าเรามาถ่อมตัวและกลับไปที่พื้นฐาน:
- ค้นหาตัวระบุรูปแบบ printf สำหรับประเภทจำนวนเต็มที่ลงนามและไม่ได้ลงชื่อที่ใหญ่ที่สุดที่คุณสามารถทำได้
- ที่รวบรวมเวลากำหนด signedness ของเวกเตอร์โดยใช้
size_typestd::is_signed_t<T> - ในขณะดำเนินการตรวจสอบว่าค่าขนาดเล็กพอที่จะใส่ลงในประเภทเป้าหมายมิฉะนั้นเพียงแค่ประกาศความล้มเหลว
- แคสต์เป็น
size_typeประเภทจำนวนเต็มที่เหมาะสม - ตอนนี้คุณสามารถใช้ค่าร่ายในการเรียก printf ได้แล้ว
PS - ในการเลือกระหว่างตัวระบุรูปแบบที่ลงนาม / ไม่ได้ลงชื่อคุณจะต้องสร้างสตริงรูปแบบแบบไดนามิกหรือเลือกระหว่างสตริงรูปแบบสองรูปแบบหรือใช้การคอมไพล์ตามเงื่อนไขเป็นต้น แต่คุณสามารถเลือกประเภทที่เซ็นชื่อใหญ่ที่สุดและแคสต์ได้เสมอ ในนั้น - ในราคาที่ล้มเหลวสำหรับขนาดที่ใหญ่ที่สุดซึ่งต้องการบิตสุดท้ายนั้น