คุณสามารถทำได้โดยไม่ต้องมีส่วนหัว:
using size_t = decltype(sizeof(int));
using size_t = decltype(sizeof 1);
using size_t = decltype(sizeof "anything");
เนื่องจากมาตรฐาน C ++ ต้องการ:
ผลมาจากsizeof
และเป็นค่าคงที่ของประเภทsizeof...
std::size_t
[หมายเหตุ: std::size_t
กำหนดไว้ในส่วนหัวมาตรฐาน<cstddef>
(18.2) - หมายเหตุ]
กล่าวอีกนัยหนึ่งมาตรฐานต้องการ:
static_assert(std::is_same<decltype(sizeof(int)), std::size_t>::value,
"This never fails.");
นอกจากนี้โปรดทราบว่าtypedef
การประกาศนี้เป็นสิ่งที่ดีอย่างสมบูรณ์ในทั่วโลกและในstd
เนมสเปซตราบเท่าที่ตรงกับtypedef
การประกาศอื่น ๆ ทั้งหมดที่มีชื่อ typedefเดียวกัน(ข้อผิดพลาดของคอมไพเลอร์จะออกในการประกาศที่ไม่ตรงกัน)
นี้เป็นเพราะ:
§7.1.3.1 typedef-nameไม่แนะนำประเภทใหม่แบบที่การประกาศคลาส (9.1) หรือการประกาศ enum ทำ
§7.1.3.3ในขอบเขตที่ไม่ใช่คลาสที่typedef
กำหนดตัวระบุสามารถใช้เพื่อกำหนดชื่อของประเภทใด ๆ ที่ประกาศในขอบเขตนั้นใหม่เพื่ออ้างถึงประเภทที่อ้างถึงอยู่แล้ว
สำหรับผู้คลางแคลงที่บอกว่านี่เป็นการเพิ่มประเภทใหม่ในเนมสเปซstd
และการกระทำดังกล่าวเป็นสิ่งต้องห้ามอย่างชัดเจนโดยมาตรฐานและนี่คือ UB และนั่นคือทั้งหมดที่อยู่ในนั้น ฉันต้องบอกว่าทัศนคตินี้เป็นการเพิกเฉยและปฏิเสธความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับปัญหาพื้นฐาน
มาตรฐานห้ามเพิ่มการประกาศและคำจำกัดความใหม่ลงในเนมสเปซstd
เนื่องจากการทำเช่นนั้นผู้ใช้อาจทำให้ไลบรารีมาตรฐานยุ่งเหยิงและทำให้ขาของเขาหลุดออกไปทั้งหมด สำหรับนักเขียนมาตรฐานมันง่ายกว่าที่จะปล่อยให้ผู้ใช้เชี่ยวชาญบางสิ่งบางอย่างและห้ามทำสิ่งอื่นใดเพื่อการวัดที่ดีแทนที่จะห้ามทุกสิ่งที่ผู้ใช้ไม่ควรทำและเสี่ยงต่อการพลาดบางสิ่งที่สำคัญ (และขานั้น) พวกเขาเคยทำมาแล้วในอดีตเมื่อกำหนดให้ไม่ต้องสร้างคอนเทนเนอร์มาตรฐานด้วยประเภทที่ไม่สมบูรณ์ในขณะที่ในความเป็นจริงคอนเทนเนอร์บางอย่างสามารถทำได้ดี (ดูThe Standard Librarian: Containers of Incomplete types by Matthew H. Austern ):
... ในที่สุดทุกอย่างก็ดูมืดมนเกินไปและเข้าใจไม่ดีเกินไป คณะกรรมการกำหนดมาตรฐานไม่คิดว่าจะมีทางเลือกอื่นนอกจากบอกว่าคอนเทนเนอร์ STL ไม่ควรทำงานกับประเภทที่ไม่สมบูรณ์ เพื่อการวัดที่ดีเราได้ใช้ข้อห้ามนั้นกับห้องสมุดมาตรฐานอื่น ๆ ด้วย
... เมื่อมองย้อนกลับไปตอนนี้เมื่อเข้าใจเทคโนโลยีมากขึ้นแล้วการตัดสินใจนั้นยังดูเหมือนถูกต้อง ใช่ในบางกรณีเป็นไปได้ที่จะใช้คอนเทนเนอร์มาตรฐานบางส่วนเพื่อให้สามารถสร้างอินสแตนซ์กับประเภทที่ไม่สมบูรณ์ได้ แต่ก็เป็นที่ชัดเจนว่าในกรณีอื่น ๆ อาจเป็นเรื่องยากหรือเป็นไปไม่ได้ ส่วนใหญ่เป็นโอกาสที่การทดสอบครั้งแรกที่เราลองใช้std::vector
นั้นเป็นหนึ่งในกรณีที่ง่าย
เนื่องจากกฎของภาษาต้องstd::size_t
เป็นไปอย่างแน่นอนdecltype(sizeof(int))
การทำnamespace std { using size_t = decltype(sizeof(int)); }
จึงเป็นหนึ่งในสิ่งที่ไม่ผิดอะไรเลย
ก่อนหน้า C ++ 11 ไม่มีdecltype
และด้วยเหตุนี้จึงไม่มีวิธีการประกาศประเภทของsizeof
ผลลัพธ์ในคำสั่งง่ายๆเพียงคำสั่งเดียวโดยไม่ต้องมีเทมเพลตมากมายที่เกี่ยวข้อง size_t
นามแฝงประเภทต่างๆบนสถาปัตยกรรมเป้าหมายที่แตกต่างกันอย่างไรก็ตามมันจะไม่ใช่วิธีการแก้ปัญหาที่หรูหราในการเพิ่มประเภทในตัวใหม่เพียงเพื่อผลลัพธ์sizeof
และไม่มีตัวพิมพ์มาตรฐานในตัว ดังนั้นวิธีแก้ปัญหาแบบพกพาที่สุดในขณะนั้นคือการใส่size_t
นามแฝงประเภทในส่วนหัวที่เฉพาะเจาะจงและจัดทำเอกสารนั้น
ใน C ++ 11 ตอนนี้มีวิธีการเขียนข้อกำหนดที่แน่นอนของมาตรฐานนั้นเป็นการประกาศง่ายๆ