สิ่งนี้ไม่ได้รับอนุญาตทั้งโดยข้อความของมาตรฐานและการใช้งานที่สำคัญหลายประการตามที่ระบุไว้ในความคิดเห็น แต่ด้วยเหตุผลที่ไม่เกี่ยวข้องอย่างสมบูรณ์
ประการแรกเหตุผล "โดยหนังสือ": จุดอินสแตนซ์ของA<C>คือตามมาตรฐาน ทันทีก่อนที่จะนิยามBและจุดอินสแตนซ์ของstd::is_default_constructible<C>ทันทีก่อนหน้านั้น:
สำหรับความเชี่ยวชาญเทมเพลตคลาส [... ] ถ้าความเชี่ยวชาญนั้นถูกทำให้เป็นอินสแตนซ์โดยปริยายเพราะมันถูกอ้างอิงจากภายในความเชี่ยวชาญของเทมเพลตอื่นถ้าบริบทที่การอ้างอิงความเชี่ยวชาญนั้นขึ้นอยู่กับพารามิเตอร์เทมเพลตและหากความเชี่ยวชาญนั้นไม่ได้สร้างอินสแตนซ์ ในการสร้างอินสแตนซ์ของเทมเพลตที่ล้อมรอบจุดของการสร้างอินสแตนซ์นั้นจะอยู่ด้านหน้าก่อนที่จะเริ่มการสร้างอินสแตนซ์ของเทมเพลตที่ล้อมรอบ มิฉะนั้นจุดของการสร้างอินสแตนซ์สำหรับความเชี่ยวชาญพิเศษนั้นจะนำหน้าการประกาศขอบเขตเนมสเปซหรือคำจำกัดความที่อ้างถึงความเชี่ยวชาญทันที
เนื่องจากจุดCนั้นไม่สมบูรณ์อย่างชัดเจนพฤติกรรมของการสร้างอินสแตนซ์std::is_default_constructible<C>จึงไม่ได้กำหนดไว้ อย่างไรก็ตามดูปัญหาหลัก 287ซึ่งจะเปลี่ยนกฎนี้
ในความเป็นจริงสิ่งนี้เกี่ยวข้องกับ NSDMI
- NSDMI นั้นแปลกเพราะพวกมันได้รับการแยกวิเคราะห์ล่าช้าหรือในสำนวนมาตรฐานพวกเขาเป็น "บริบทที่สมบูรณ์แบบ"
- ดังนั้นที่
= 0สามารถในหลักการหมายถึงสิ่งที่อยู่ในที่ยังไม่ได้ประกาศเพื่อให้การดำเนินการไม่สามารถจริงๆพยายามที่จะแยกมันจนกว่าจะได้จบด้วยBB
- การทำให้คลาสเสร็จสมบูรณ์จำเป็นต้องมีการประกาศโดยนัยของฟังก์ชันสมาชิกพิเศษโดยเฉพาะคอนสตรัคเตอร์เริ่มต้นเนื่องจาก
Cไม่มีคอนสตรัคเตอร์ที่ประกาศ
- บางส่วนของการประกาศนั้น (constexpr-ness, noexcept-ness) ขึ้นอยู่กับคุณสมบัติของ NSDMI
- ดังนั้นหากคอมไพเลอร์ไม่สามารถแยกวิเคราะห์ NSDMI มันจะไม่สามารถเรียนได้
- เป็นผลให้เมื่อถึงจุดที่มัน instantiates
A<C>มันคิดว่าCมันไม่สมบูรณ์
พื้นที่ทั้งหมดที่เกี่ยวข้องกับภูมิภาคที่มีการแยกวิเคราะห์ล่าช้านี้ไม่ได้รับการเน้นยิบอย่างเด็ดขาด อาจใช้เวลาสักครู่ก่อนทำความสะอาด