แบบฟอร์มไม่ถูกต้อง:
int &z = 12;
แบบฟอร์มที่ถูกต้อง:
int y;
int &r = y;
คำถาม :
ทำไมรหัสแรกผิด? "ความหมาย " ของข้อผิดพลาดในชื่อเรื่องคืออะไร?
แบบฟอร์มไม่ถูกต้อง:
int &z = 12;
แบบฟอร์มที่ถูกต้อง:
int y;
int &r = y;
คำถาม :
ทำไมรหัสแรกผิด? "ความหมาย " ของข้อผิดพลาดในชื่อเรื่องคืออะไร?
(ostringstream() << "x=" << x).str()
คำตอบ:
C ++ 03 3.10 / 1 พูดว่า: "ทุกนิพจน์เป็น lvalue หรือ rvalue" สิ่งสำคัญคือต้องจำไว้ว่าค่า lvalueness เทียบกับ rvalueness เป็นคุณสมบัติของการแสดงออกไม่ใช่ของวัตถุ
Lvalues ออบเจ็กต์ชื่อที่คงอยู่นอกเหนือจากนิพจน์เดียว ตัวอย่างเช่นobj, *ptr, ptr[index]และ++xเป็น lvalues ทั้งหมด
Rvalues คือชั่วคราวที่ระเหยเมื่อสิ้นสุดนิพจน์เต็มที่พวกมันมีชีวิตอยู่ ("ที่อัฒภาค") ตัวอย่างเช่น1729, x + y, std::string("meow")และx++มี rvalues ทั้งหมด
แอดเดรส - ของโอเปอเรเตอร์กำหนดให้ "ตัวถูกดำเนินการต้องเป็นค่า lvalue" ถ้าเราสามารถใช้แอดเดรสของนิพจน์หนึ่งนิพจน์นั้นคือ lvalue มิฉะนั้นจะเป็น rvalue
&obj; // valid
&12; //invalid
int & = 12;นิพจน์จึงไม่ถูกต้องมาตรฐานกล่าวว่าลิเทอรัลของสตริงเป็นค่า lvalue ตัวอักษรอื่น ๆ เป็นค่า rvalues
std::string("meow")สร้างออบเจ็กต์ประเภทstd::stringและให้ค่า r ที่กำหนดอ็อบเจ็กต์1729นี้ไม่มีผลข้างเคียงและให้ค่า 1729 เป็น rvalue intของพิมพ์
"Lvalues name objects that persist beyond a single expression."นี้เป็นคำสั่งที่ถูกต้อง 100% ในทางกลับกันตัวอย่างของคุณ(const int &)1ไม่ถูกต้องเนื่องจากไม่ใช่วัตถุ "ชื่อ"
int &z = 12;
ทางด้านขวามืออ็อบเจ็กต์ชั่วคราวประเภทintถูกสร้างขึ้นจากอินทิกรัลลิเทอรั12ล แต่ชั่วคราวไม่สามารถถูกผูกไว้กับการอ้างอิงที่ไม่ใช่ const ดังนั้นข้อผิดพลาด เหมือนกับ:
int &z = int(12); //still same error
เหตุใดจึงมีการสร้างชั่วคราว เนื่องจากการอ้างอิงต้องอ้างถึงอ็อบเจ็กต์ในหน่วยความจำและสำหรับอ็อบเจ็กต์ที่มีอยู่นั้นจะต้องถูกสร้างขึ้นก่อน เนื่องจากวัตถุไม่มีชื่อจึงเป็นวัตถุชั่วคราว มันไม่มีชื่อ จากคำอธิบายนี้มันค่อนข้างชัดเจนว่าทำไมกรณีที่สองถึงใช้ได้
วัตถุชั่วคราวสามารถถูกผูกไว้กับการอ้างอิง const ซึ่งหมายความว่าคุณสามารถทำได้:
const int &z = 12; //ok
เพื่อความสมบูรณ์ฉันต้องการเพิ่มเติมว่า C ++ 11 ได้แนะนำ rvalue-reference ซึ่งสามารถผูกกับวัตถุชั่วคราวได้ ดังนั้นใน C ++ 11 คุณสามารถเขียนสิ่งนี้:
int && z = 12; //C+11 only
โปรดทราบว่ามี&&intead ของ&. นอกจากนี้โปรดทราบว่าconstไม่จำเป็นอีกต่อไปแม้ว่าออบเจ็กต์ที่zผูกกับเป็นอ็อบเจ็กต์ชั่วคราวที่สร้างขึ้นจากอินทิกรัล - ลิเทอรั12ล
ตั้งแต่ C ++ 11 ได้แนะนำrvalue อ้างอิง , int&นี้เรียกว่าต่อจากนี้ไปlvalue อ้างอิง
12int&เป็นค่าคงที่รวบรวมเวลาที่ไม่สามารถเปลี่ยนแปลงได้แตกต่างจากข้อมูลอ้างอิงจาก สิ่งที่คุณสามารถทำได้คือ
const int& z = 12;
void f( vector<int> const & )ซึ่งเป็นสำนวนที่จะส่งผ่านเวกเตอร์ที่ไม่ต้องแก้ไข ปัญหาตอนนี้คือf( vector<int>(5) )จะไม่ถูกต้องและผู้ใช้จะต้องจัดเตรียมโอเวอร์โหลดที่แตกต่างออกvoid f( vector<int> v ) { f(v); }ไป
f( vector<int>(5) )คอมไพลเลอร์จะสร้างชั่วคราวจากนั้นเชื่อมโยงการอ้างอิงกับชั่วคราวนั้นและในทำนองเดียวกัน หากมีการแปลงโดยนัยจาก5โดยตรง สิ่งนี้ช่วยให้คอมไพลเลอร์สร้างลายเซ็นเดียวสำหรับฟังก์ชันและเปิดใช้งานฟังก์ชันผู้ใช้คนเดียว จากนั้นจะมีการกำหนดพฤติกรรมที่คล้ายกันสำหรับการใช้การอ้างอิงคงที่เพื่อความสอดคล้อง
T const & r = *ptr;การใช้rฟังก์ชันใด ๆ ในภายหลังสามารถแทนที่ได้*ptrและrไม่จำเป็นต้องมีอยู่ในรันไทม์) หรืออาจต้องใช้งานโดยเก็บที่อยู่ของวัตถุที่เป็นนามแฝง (พิจารณาจัดเก็บข้อมูลอ้างอิงในฐานะสมาชิกของวัตถุ) ซึ่งใช้เป็นตัวชี้การอ้างอิงอัตโนมัติ
นี่คือกฎของภาษา C ++:
12) คือ "rvalue"int &ri = 12;เป็นรูปแบบที่ไม่ถูกต้องคุณต้องเข้าใจว่านี่คือกฎ C ++ พวกเขาเป็นเพียง
เป็นเรื่องง่ายที่จะประดิษฐ์ภาษาอื่นพูดว่า C ++ 'โดยมีกฎที่แตกต่างกันเล็กน้อย ใน C ++ 'จะได้รับอนุญาตให้สร้างการอ้างอิงที่ไม่ใช่ const ด้วย rvalue ไม่มีอะไรที่ไม่สอดคล้องกันหรือเป็นไปไม่ได้ที่นี่
แต่จะอนุญาตให้มีโค้ดที่มีความเสี่ยงซึ่งโปรแกรมเมอร์อาจไม่ได้รับสิ่งที่เขาตั้งใจไว้และนักออกแบบ C ++ ก็ตัดสินใจอย่างถูกต้องที่จะหลีกเลี่ยงความเสี่ยงนั้น
การอ้างอิงคือ "ตัวชี้ที่ซ่อนอยู่" (ไม่ใช่ค่าว่าง) สำหรับสิ่งที่เปลี่ยนแปลงได้ (ค่า lvalues) คุณไม่สามารถกำหนดให้เป็นค่าคงที่ มันควรจะเป็น "ตัวแปร"
แก้ไข ::
ฉันกำลังคิดถึง
int &x = y;
เกือบจะเทียบเท่ากับ
int* __px = &y;
#define x (*__px)
__pxชื่อใหม่อยู่ที่ไหนและ#define xผลงานเฉพาะในบล็อกที่มีการประกาศxการอ้างอิง
const:)
const