A () = A () - ทำไมถึงรวบรวม?


85
class A {};

int main() {
 A() = A();
 return 0; 
}

ทำไมโค้ดนี้จึงคอมไพล์ ไม่ควรมีข้อผิดพลาดที่ทางด้านซ้ายของตัวดำเนินการกำหนดค่าควรวาง lvalue? A () lvalue คืออะไร? g ++ 4.7 เวอร์ชัน

คำตอบ:


88

สำหรับในตัวชนิดที่คุณต้องการจะเป็นที่ถูกต้อง: ในตัวดำเนินการกำหนดต้องมีการปรับแก้lvalueทางด้านซ้ายมือ

อย่างไรก็ตามนี่ไม่ได้ใช้ตัวดำเนินการในตัว แต่เป็นการโอเวอร์โหลดที่คลาสประกาศโดยปริยาย นี่คือฟังก์ชันสมาชิกเทียบเท่ากับ

A().operator=(A());

และฟังก์ชั่นสมาชิกสามารถถูกเรียกบนrvalues


7
มันไม่ได้คัดลอกการเริ่มต้น?
ละอองดาว

13
@ ชื่อ: ไม่มันไม่ใช่การกำหนดค่าเริ่มต้น
Mike Seymour

1
@ paul23: นั่นเป็นความจริง (สมมติว่าคุณoperator=ไม่ได้หมายความว่าoperator()) แต่ไม่เกี่ยวข้องกับคำถามมากนัก ตัวอย่างไม่ได้ทำอะไรกับผลลัพธ์ของงาน
Mike Seymour

3
@ paul23 A()ไม่เรียกมันสร้างวัตถุของการพิมพ์operator() A
interjay

3
ไม่สามารถเริ่มต้นได้เนื่องจากไม่มีการประกาศ
Kos

32

หากคุณต้องการจริงๆคุณไม่สามารถรวบรวมด้วย C ++ 11 ได้:

class A {
    template <typename T>
    void operator=(T&&) && = delete; // no op= for rvalues

    // generate other special members normally
    A() = default;
    A(A const&) = default;
    A(A&&) = default;
    ~A() = default;
    // op= only for lvalues
    A& operator=(A&&) & = default;
    A& operator=(A const&) & = default;
};

int main() {
 A() = A(); // error
 return 0; 
}

( ตัวอย่างสด )

สังเกต&และ&&(aka ref-qualifiers) ในตอนท้ายของการประกาศของoperator=แบบฟอร์มต่างๆ สิ่งนี้ทำให้การประกาศเหล่านั้นถูกเลือกสำหรับ lvalues ​​และ rvalues ​​ตามลำดับ อย่างไรก็ตามเวอร์ชัน rvalue เมื่อเลือกโดยความละเอียดเกินจะทำให้โปรแกรมมีรูปแบบที่ไม่เหมาะสมเนื่องจากถูกลบ

อย่างไรก็ตามตัวดำเนินการที่สร้างขึ้นเริ่มต้น = ไม่มี ref-qualifier ใด ๆ ซึ่งหมายความว่าสามารถเรียกได้ทั้ง lvalues ​​และ rvalues นั่นเป็นเหตุผลที่โค้ดในคำถามรวบรวมแม้ว่าจะA()เป็นค่า rvalue ก็ตาม


1

คอมไพเลอร์ C ++ จัดเตรียมคลาสทั้งหมดด้วยตัวสร้างเริ่มต้นนั่นคือสิ่งที่เกิดขึ้นตามรหัสของคุณเมื่อคุณพูดว่า A () = A (); เพียงแค่เรียกตัวสร้างด้วยอ็อบเจ็กต์นิรนามและฟังก์ชันจะส่งคืนการอ้างอิงไปยังอ็อบเจ็กต์ที่สร้างขึ้น (โดยนัย) แค่นั้นแหละ...

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