ข้อผิดพลาด: การใช้ฟังก์ชันที่ถูกลบ


122

ฉันทำงานกับรหัส C ++ ที่เพื่อนเขียนและได้รับข้อผิดพลาดต่อไปนี้ที่ฉันไม่เคยเห็นมาก่อนเมื่อคอมไพล์กับ gcc4.6:

error: use of deleted function

GameFSM_<std::array<C, 2ul> >::hdealt::hdealt()’ is implicitly deleted because the default definition would be ill-formed:
uninitialized non-static const member const h_t FlopPokerGameFSM_<std::array<C, 2ul> >::hdealt::h

แก้ไข: สิ่งนี้มาจากส่วนหนึ่งของโค้ดโดยใช้ boost MSM: Boost Webpage

แก้ไข 2: ไม่มีการ= delete()ใช้ที่ใดก็ได้ในซอร์สโค้ด

โดยทั่วไปแล้วข้อผิดพลาดนี้หมายถึงอะไร? ฉันควรมองหาอะไรเมื่อเกิดข้อผิดพลาดประเภทนี้


4
และรหัสที่คุณกำลังรวบรวม?
ColWhi

ฉันสงสัยมากขึ้นว่าข้อผิดพลาดหมายถึงอะไร? ฉันต้องโพสต์รหัสสำหรับสิ่งนั้นด้วยหรือไม่?
shuttle87

1
gcc.gnu.org/bugzilla/show_bug.cgi?id=47417อาจช่วยได้คุณใช้บูสต์ด้วยหรือไม่
ColWhi

@Sasquiha ใช่ฉันใช้ Boost MSM
shuttle87

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

คำตอบ:


171

เกิดข้อผิดพลาดอย่างชัดเจนกล่าวว่าสร้างเริ่มต้นได้ถูกลบไปแล้วโดยปริยาย มันยังบอกว่าทำไม: คลาสมีตัวแปร const ที่ไม่คงที่ซึ่งจะไม่เริ่มต้นโดย ctor เริ่มต้น

class X {
    const int x;
};

เนื่องจากX::xเป็นconstค่าเริ่มต้น - แต่ ctor เริ่มต้นจะไม่เริ่มต้นตามปกติ (เนื่องจากเป็นประเภท POD) ดังนั้นในการรับ ctor เริ่มต้นคุณต้องกำหนดด้วยตัวเอง (และต้องเริ่มต้นx) คุณจะได้รับสถานการณ์เดียวกันกับสมาชิกที่เป็นข้อมูลอ้างอิง:

class X { 
    whatever &x;
};

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

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

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


@Jeffry Coffin: ข้อความแสดงข้อผิดพลาดจริงถูกโพสต์เป็นการแก้ไขข้อความแสดงข้อผิดพลาดเริ่มต้นที่โพสต์เท่านั้นC++ error: use of deleted function
Alok บันทึก

1
@ แอล: ขออภัยฉันน่าจะชัดเจนว่าฉันไม่ได้ตั้งใจว่าเป็นการดูถูกหรืออะไรเกี่ยวกับคำสั่งนั้นเพียงแค่สิ่งที่มีอยู่ในปัจจุบันทำให้เห็นได้ชัดว่าคำตอบเหล่านั้นไม่ถูกต้อง
Jerry Coffin

ไม่มีปัญหาฉันไม่ได้ตั้งใจจะยืนกราน ... คำตอบของคุณยอดเยี่ยมและอธิบายสถานการณ์ได้ดีที่สุด +1 จากฉัน :)
Alok Save

ฉันคิดว่าคุณอาจช่วยฉันแก้ปัญหาได้ที่นี่โปรด: stackoverflow.com/questions/23349524/…
Saher Ahwal

2
@OllieFord: ขึ้นอยู่กับ จะเกิดอะไรขึ้นถ้า (เช่น) คุณกำหนดวัตถุที่มีค่าหนึ่งในฟิลด์นั้นให้กับอีกค่าหนึ่งที่มีค่าต่างกันในฟิลด์นั้น ถ้าควรจะเขียนทับก็จะไม่สามารถเป็น const หากไม่ควรอนุญาตเลยค่าอาจเป็นส่วนหนึ่งของประเภทจริงๆ (เช่นพารามิเตอร์เทมเพลตหากทราบในเวลาคอมไพล์)
Jerry Coffin

11

deletedคุณกำลังใช้ฟังก์ชั่นซึ่งถูกระบุว่าเป็น
เช่น:

int doSomething( int ) = delete;

= ลบเป็นคุณลักษณะใหม่ของ C ++ 0x หมายความว่าคอมไพเลอร์ควรหยุดรวบรวมทันทีและบ่นว่า "ฟังก์ชันนี้ถูกลบ" เมื่อผู้ใช้ใช้ฟังก์ชันดังกล่าว

=deleteถ้าคุณเห็นข้อผิดพลาดนี้คุณควรตรวจสอบการประกาศฟังก์ชั่นสำหรับ

หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับคุณลักษณะใหม่นี้นำมาใช้ใน C ++ 0x ตรวจสอบนี้ออก


7
ด้วยความอยากรู้อยากเห็นเมื่อไหร่ที่การทำสิ่งนั้นจะเป็นประโยชน์?
Pepe

@Peter: เพื่อป้องกันการแปลงโดยปริยาย
R.Martinho Fernandes

7
จริงๆแล้วมันบอกว่า"ลบโดยปริยายเพราะ ... "ตัวอย่างข้างต้นจะชัดเจน
Georg Fritzsche

@Peter R: ดูเหมือนจะเป็นตัวอย่าง: en.wikipedia.org/wiki/…
shuttle87

1
@Downvoter: ข้อความแสดงข้อผิดพลาดที่เกิดขึ้นจริงถูกโพสต์เป็นการแก้ไขข้อความแสดงข้อผิดพลาดเริ่มต้นที่โพสต์เท่านั้นC++ error: use of deleted function
Alok บันทึก

4

gcc 4.6 รองรับคุณสมบัติใหม่ของฟังก์ชันที่ถูกลบซึ่งคุณสามารถเขียนได้

hdealt() = delete;

เพื่อปิดใช้งานตัวสร้างเริ่มต้น

ที่นี่คอมไพเลอร์เห็นได้ชัดว่าไม่สามารถสร้างตัวสร้างเริ่มต้นได้และ=delete'd ให้คุณ


2

ฉันพบข้อผิดพลาดนี้เมื่อรับช่วงจากคลาสนามธรรมและไม่ได้ใช้วิธีเสมือนจริงทั้งหมดในคลาสย่อยของฉัน


1
ในทำนองเดียวกันฉันได้รับสิ่งเดียวกันโดยได้มาpublic virtualจากคลาสพื้นฐานระดับ 2 ซึ่งคลาสพื้นฐานระดับ 1 มีตัวสร้างเริ่มต้นที่ถูกลบอย่างชัดเจน การลบvirtualแก้ไขปัญหาโดยไม่ต้องใช้วิธีการทั้งหมด
Maitre Bart

1

ในมาตรฐาน C ++ 0x ปัจจุบันคุณสามารถปิดการใช้งานตัวสร้างเริ่มต้นอย่างชัดเจนด้วยไวยากรณ์การลบเช่น

MyClass() = delete;

Gcc 4.6 เป็นเวอร์ชันแรกที่รองรับไวยากรณ์นี้อาจเป็นปัญหา ...


Gcc 4.6 is the first version to support this syntaxฉันเดาว่านั่นจะอธิบายได้ว่าทำไมฉันไม่เคยเห็นมาก่อนเพราะฉันเพิ่งเริ่มใช้ gcc4.6 เมื่อไม่นานมานี้
shuttle87

2
ฉันใช้ไวยากรณ์นี้กับ GCC 4.5 มาหลายปีแล้ว ฉันหมายถึงวัน
R.Martinho Fernandes

อ่าฉันคงคิดถึง ctors ที่ได้รับมอบหมายซึ่งอยู่ใน GCC 4.6
jarmond

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