การขว้างและจับใจ ints ทำงานอย่างไร


14

ด้วยรหัสนี้:

int main()
{
    try
    {
        throw -1;
    }
    catch (int& x)
    {
        std::cerr << "We caught an int exception with value: " << x << std::endl;
    }
    std::cout << "Continuing on our merry way." << std::endl;

    return 0;
}

เรามี:

/tmp$ ./prorgam.out
Continuing on our merry way
We caught an int exception with value: -1

อย่างไรcatchบล็อกอ่าน-1เป็นint&? เราไม่สามารถกำหนดค่าให้กับการอ้างอิง lvalue ที่ไม่ใช่ const

และทำไมstd::coutคำสั่งที่สองจึงถูกดำเนินการก่อนstd::cerrคำสั่งแรก?


2
คุณแน่ใจหรือไม่ว่านี่เป็นผลลัพธ์ที่แท้จริงที่คุณจะได้รับ We caught an int exception with value: -1บรรทัดควรได้รับการตีพิมพ์ครั้งแรก
HolyBlackCat

1
@Scheff ขออภัยคุณมีสิทธิเป็นผลผลิตที่ได้จะถูกนำไปไม่ได้error stream standard stream
Ghasem Ramezani


2
@ FrançoisAndrieuxเหตุผลที่ได้รับอนุญาตคือมีความหมายต่าง ๆ เกิดขึ้น โดยทั่วไปแล้วด้วยชั่วคราวคุณไม่ทราบว่าจะเกิดอะไรขึ้นกับมันชั่วคราวดังนั้นจึงมีการตัดสินใจที่จะอนุญาตให้มีการอ้างอิง const กับขมับเท่านั้น ด้วยข้อยกเว้นเรารู้อายุการใช้งานของวัตถุและเราอาจต้องการที่จะปรับเปลี่ยนมันและ rethrow มันเป็นบริบทที่สูงขึ้น เพื่ออำนวยความสะดวกนั้นมาตรฐานอนุญาตให้มีการผูกกับการอ้างอิง lvalue ที่ไม่ใช่ const
NathanOliver

1
@ FrançoisAndrieux throwสร้างสำเนา (หรือย้าย) วัตถุที่คุณส่งไป การอ้างอิงผูกกับสำเนานั้น มันสมเหตุสมผลแล้วที่การลอกเลียนแบบจะเป็น lvalue
HolyBlackCat

คำตอบ:


10

ไม่เป็นไรเพราะ[ยกเว้น. โยน] / 3

โยนข้อยกเว้นคัดลอกเริ่มต้น ([dcl.init], [class.copy.ctor]) วัตถุชั่วคราวที่เรียกว่าวัตถุยกเว้น lvalue แสดงถึงการชั่วคราวจะใช้ในการเริ่มต้นตัวแปรประกาศในการจัดการการจับคู่ ([ยกเว้น. HANDLE])

ฉันเน้น

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


1
แต่สิ่งที่มีลำดับที่ข้อความปรากฏขึ้น?
Tomáš Zato - Reinstate Monica

8

จากการอ้างอิงนี้throw :

แตกต่างจากวัตถุชั่วคราวอื่น ๆ วัตถุข้อยกเว้นจะถือเป็นอาร์กิวเมนต์ lvalue เมื่อเริ่มต้นพารามิเตอร์ catch clause เพื่อให้สามารถจับได้โดยการอ้างอิง lvalue การแก้ไขและการโยนใหม่

ดังนั้นในขณะที่ "วัตถุ" นั้นชั่วคราวมันยังคงเป็น lvalue และคุณสามารถรับมันได้โดยการอ้างอิง

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