ตัวดำเนินการที่อยู่คู่ C ++? (&&)


148

ฉันกำลังอ่านซอร์สโค้ด STL และฉันไม่รู้ว่า&&ตัวดำเนินการที่อยู่ควรจะทำอะไร นี่คือตัวอย่างโค้ดจากstl_vector.h:

vector&
operator=(vector&& __x) // <-- Note double ampersands here
{
    // NB: DR 675.
    this->clear();
    this->swap(__x); 
    return *this;
}

"Address of Address" มีความหมายหรือไม่? เหตุใดจึงมีตัวดำเนินการที่อยู่สองตัวแทนที่จะเป็นเพียงตัวดำเนินการเดียว


3
อาจเป็นที่อยู่ของข้อมูลอ้างอิง
Gabe

1
@ กาเบ; เป็นการประกาศเพื่อให้เป็นการอ้างอิงถึงข้อมูลอ้างอิงซึ่งไม่สมเหตุสมผลเนื่องจากการอ้างอิงนั้นไม่สามารถแก้ไขได้ address-of สามารถใช้ได้เฉพาะในโค้ดเท่านั้นไม่ใช่เมื่อประกาศ (พารามิเตอร์เช่นในกรณีนี้หรืออื่น ๆ ) ไม่เคยเห็นอะไรแบบนี้มาก่อน
falstro

5
แม้ว่าจะมีเพียงตัวเดียว&แต่ก็ไม่มีส่วนเกี่ยวข้องกับแอดเดรสของโอเปอเรเตอร์ แต่ให้ความหมายว่า__xเป็นการอ้างอิงแทน
sepp2k

คำตอบ:



188

&&เป็นสิ่งใหม่ใน C ++ 11 int&& aหมายถึง "a" คือการอ้างอิงค่า r &&โดยปกติจะใช้เพื่อประกาศพารามิเตอร์ของฟังก์ชันเท่านั้น และใช้เฉพาะนิพจน์ r-value หากคุณไม่ทราบว่า r-value คืออะไรคำอธิบายง่ายๆคือไม่มีที่อยู่หน่วยความจำ เช่นตัวเลข 6 และอักขระ 'v' เป็นค่า r ทั้งคู่ int aa คือ l-value แต่(a+2)เป็น r-value ตัวอย่างเช่น:

void foo(int&& a)
{
    //Some magical code...
}

int main()
{
    int b;
    foo(b); //Error. An rValue reference cannot be pointed to a lValue.
    foo(5); //Compiles with no error.
    foo(b+3); //Compiles with no error.

    int&& c = b; //Error. An rValue reference cannot be pointed to a lValue.
    int&& d = 5; //Compiles with no error.
}

หวังว่าจะเป็นข้อมูล


12
ตัวอย่างเดียวที่ฉันต้องการให้คุณเพิ่มคือวิธีการทำงานกับ std :: move แสดงสิ่งที่จะเกิดขึ้นกับint&& c = std::move( b );ฯลฯ
Zzzach ...

5
ดูเหมือนว่าSravani Sลอกเลียนโจ๋งครึ่มจากคุณ TutorialsPoint บน 15 กุมภาพันธ์ 2018, ที่นี่
Gabriel Staples

6
ฉันเพิ่งส่งบทแนะนำชี้ข้อความนี้ บทความที่เป็นลอกเลียนโดยพวกเขามีลักษณะเช่นนี้
Gabriel Staples

87

&&เป็นสิ่งใหม่ใน C ++ 11 และแสดงว่าฟังก์ชันยอมรับการอ้างอิง RValueนั่นคือการอ้างอิงถึงอาร์กิวเมนต์ที่กำลังจะถูกทำลาย


@bronekk: คุณเห็นวันที่โพสต์ข้อความนี้หรือไม่? ไม่ได้เผยแพร่ ณ วันที่ 28 ธันวาคม 2553
Billy ONeal

ขออภัยที่ลบออกตอนนี้ คราวหน้าจะได้ระวังให้มากขึ้น :)
bronekk

36

ดังที่คำตอบอื่น ๆ ได้กล่าวไว้&&โทเค็นในบริบทนี้เป็นสิ่งใหม่สำหรับ C ++ 0x (มาตรฐาน C ++ ถัดไป) และแสดงถึง "การอ้างอิง rvalue"

การอ้างอิง Rvalue เป็นสิ่งใหม่ที่สำคัญกว่าในมาตรฐานที่กำลังจะมาถึง พวกเขาเปิดใช้งานการสนับสนุนความหมาย 'ย้าย' บนวัตถุและอนุญาตการส่งต่อการเรียกฟังก์ชันที่สมบูรณ์แบบ

เป็นหัวข้อที่ค่อนข้างซับซ้อน - หนึ่งในบทนำที่ดีที่สุด (ไม่ใช่แค่คร่าวๆ) เป็นบทความของ Stephan T. Lavavej, "Rvalue References: C ++ 0x Features in VC10, Part 2"

โปรดทราบว่าบทความนี้ยังอ่านค่อนข้างหนัก แต่ก็คุ้มค่า และแม้ว่าจะอยู่ในบล็อก Microsoft VC ++ แต่ข้อมูลทั้งหมด (หรือเกือบทั้งหมด) สามารถใช้ได้กับคอมไพเลอร์ C ++ 0x ใด ๆ


&&โทเค็นตัวเองไม่ได้ใหม่ ความหมายในการประกาศคือ แต่คุณรู้ว่า
aschepler

เป็นเรื่องใหม่ในบริบทนี้ แต่เป็นแบบดั้งเดิมมากสำหรับ C / C ++ ที่จะโอเวอร์โหลดโทเค็นเพื่อให้มีความหมายที่แตกต่างกันในบริบทที่แตกต่างกัน
Martin York

1
@aschkleper - แน่นอน ... ตรรกะและตัวดำเนินการไม่ได้เข้ามาในความคิดของฉัน ฉันจะอัปเดตคำตอบ
Michael Burr

4

ฉันเชื่อว่าเป็นผู้ดำเนินการย้าย operator=เป็นผู้ดำเนินการมอบหมายพูดvector x = vector y. การclear()เรียกใช้ฟังก์ชันฟังดูเหมือนกำลังลบเนื้อหาของเวกเตอร์เพื่อป้องกันการรั่วไหลของหน่วยความจำ ตัวดำเนินการส่งกลับตัวชี้ไปยังเวกเตอร์ใหม่

ทางนี้,

std::vector<int> a(100, 10);
std::vector<int> b = a;
for(unsigned int i = 0; i < b.size(); i++)
{
    std::cout << b[i] << ' ';
}

แม้ว่าเราจะให้เวกเตอร์เป็นค่าเวกเตอร์ b ก็มีค่า มันคือความมหัศจรรย์ของoperator=()!

MSDN - วิธีสร้างตัวสร้างการย้าย


1
คำตอบของคุณคืออะไรเพิ่มสำหรับคำถามอายุ 4 ขวบซึ่งยังไม่ได้กล่าวถึงในคำตอบอื่น ๆ
Masked Man

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