const void คืออะไร?


90

คำอธิบายของstd::is_voidระบุว่า:

ระบุค่าคงที่ของสมาชิกที่เท่ากับจริงถ้า T เป็นประเภทโมฆะ const โมฆะโมฆะระเหยหรือ const โมฆะระเหย

แล้วจะconst voidเป็นvolatile voidอย่างไรหรือก.

คำตอบนี้ระบุว่าconst voidประเภทการส่งคืนจะไม่ถูกต้อง (อย่างไรก็ตามคอมไพล์ใน VC ++ 2015)

const void foo() { }

ถ้าตามมาตรฐานแล้วconst voidไม่ถูกต้อง (VC ผิด) - แล้วคือconst voidอะไร?


15
คำตอบที่คุณเชื่อมโยงไปไม่ได้ระบุว่ามันจะไม่ถูกต้อง แต่ก็ระบุว่ามันจะ "ไม่มีความหมาย" ซึ่งผมจะแปลว่า "ไม่ได้ให้ประโยชน์ใด ๆvoidโดยไม่มีconst"

@hvd คำตอบระบุว่าคอมไพเลอร์ควรเตือน / ข้อผิดพลาดเกี่ยวกับคุณสมบัติดังกล่าว โดยที่ฉันคิดว่ามาตรฐาน C ++ ไม่อนุญาตให้มีคุณสมบัติvoid
Ajay

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

@Ajay มาตรฐานไม่ได้ระบุว่าควรมีคำเตือนเมื่อคุณใช้รหัสที่ไม่มีความหมาย เป็นการตัดสินใจโดย gcc เพื่อให้คำแนะนำเพิ่มเติมแก่คุณว่ารหัสนี้ไม่ได้ทำอะไรเลย แต่ VC ไม่ผิด แต่อย่างใด
user1942027

3
@Ajay คำตอบระบุว่าเสียงดังส่งเสียงเตือนและในความเห็นของผู้เขียนคอมไพเลอร์อื่น ๆ ควร หากมาตรฐานไม่อนุญาตอาจเป็นข้อผิดพลาดไม่ใช่คำเตือน
molbdnilo

คำตอบ:


94

const voidเป็นประเภทที่คุณสามารถสร้างตัวชี้ได้ มันคล้ายกับตัวชี้โมฆะธรรมดา แต่การแปลงจะทำงานต่างกัน ตัวอย่างเช่นconst int*ไม่สามารถแปลง a โดยปริยายเป็น a void*ได้ แต่สามารถแปลงเป็นconst void*ไฟล์. ในทำนองเดียวกันถ้าคุณมีconst void*คุณไม่สามารถstatic_castไปยังint*แต่คุณสามารถไปที่static_castconst int*

const int i = 10;
void* vp = &i;                           // error
const void* cvp = &i;                    // ok
auto ip = static_cast<int*>(cvp);        // error
auto cip = static_cast<const int*>(cvp); // ok

4
แม้ว่าคำตอบของคุณจะดี แต่ก็ไม่ได้ระบุเหตุผลของconst voidแต่คำตอบนั้นอยู่รอบ ๆ ตัวชี้ที่เป็นโมฆะและไม่ใช่โมฆะ [with (non-) const-ness]
Ajay

26
@Ajay: ฉันไม่เห็นด้วย เป็นเหตุผลเดียวที่คุณเคยจะเห็นconst void* const voidมันอาจถูกส่งต่อไปรอบ ๆ เป็นอาร์กิวเมนต์แม่แบบ แต่ประเภทอาร์กิวเมนต์นั้นจะถูกสร้างอินสแตนซ์ด้วย a *ต่อท้ายเท่านั้น
Benjamin Lindley

@BenjaminLindley คุณอาจเห็นconst voidในคำถามที่ถามโดยนักกฎหมายภาษา
cpplearner

3
@Ajay: เมื่อถึงจุดหนึ่งคำถามนี้ก็กลายเป็นคำถามเชิงปรัชญา ว่า "เหตุผล" ของconst voidคือการที่ทุกประเภทใน C ++ constสามารถทำ มัน "มีอยู่" แบบเดียวกับที่voidมีอยู่ คำตอบของ @Benjamin Lindley อธิบายว่ามันคืออะไรเมื่อคุณเห็นมันและคุณใช้มันอย่างไร
Chris Beck

23

ในฐานะที่เป็นvoid, const voidเป็นชนิดที่เป็นโมฆะ อย่างไรก็ตามหากconst voidเป็นประเภทผลตอบแทนconstจะไม่มีความหมาย (แม้ว่าจะถูกกฎหมาย!) เนื่องจาก[expr] / 6 :

หาก prvalue ในตอนแรกมีประเภท " cv T " โดยที่Tเป็นประเภทที่ไม่ใช่อาร์เรย์แบบไม่มีเงื่อนไขที่ไม่มีเงื่อนไขประเภทของนิพจน์จะถูกปรับเป็นTก่อนที่จะมีการวิเคราะห์เพิ่มเติม

อย่างไรก็ตามเป็นประเภทที่ถูกต้องและเกิดขึ้นในเช่นฟังก์ชันไลบรารีมาตรฐาน Cซึ่งใช้เพื่อรับรองความถูกต้องของตัวชี้อาร์กิวเมนต์: int const*ไม่สามารถแปลงเป็นได้void*แต่void const*.


const voidเนื่องจากประเภทการส่งคืนจะส่งผลต่อประเภทฟังก์ชันดังนั้นจึงไม่มีความหมายอย่างสมบูรณ์
cpplearner

1
@cpplearner ยกเว้นในแง่ของการใช้งานจริงทุกประการเนื่องจากทั้งลายเซ็นของฟังก์ชันหรือประเภทของการเรียกใช้ไม่ได้รับผลกระทบ
Columbo

มันสามารถเปลี่ยนลายเซ็นของเทมเพลตฟังก์ชันได้ +1 กระนั้น
cpplearner

@cpplearner พอใช้ - แต่ก็ยังเสียการกดแป้นพิมพ์
Columbo

ปกติเราจะเห็น: const int * ไม่สามารถไปที่ void * แต่ const void *
mgouin

18

ประเภทอาจเป็นผลมาจากเทมเพลต แม่แบบอาจรัฐconst Tและยกตัวอย่างประกอบกับเป็นTvoid

คำตอบที่เชื่อมโยงผิดหรือค่อนข้าง จำกัด ในมุมมองในการที่จะนับถือกรณีพิเศษของชนิดที่ไม่ใช่แม่แบบและได้แล้วconst voidอาจจะไม่มีความหมายแต่มันเป็นรหัสที่ถูกต้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.