การเข้าถึงองค์ประกอบแผนที่ C ++ const


102

ฉันพยายามใช้ตัวดำเนินการ [] เข้าถึงองค์ประกอบในแมป const C ++ แต่วิธีนี้ล้มเหลว ฉันยังพยายามใช้ "at ()" เพื่อทำสิ่งเดียวกัน มันได้ผลในครั้งนี้ อย่างไรก็ตามฉันไม่พบข้อมูลอ้างอิงใด ๆ เกี่ยวกับการใช้ "at ()" เพื่อเข้าถึงองค์ประกอบในแผนที่ const C ++ "at ()" เป็นฟังก์ชันที่เพิ่มใหม่ในแผนที่ C ++ หรือไม่ ฉันจะหาข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ที่ไหน ขอบคุณมาก!

ตัวอย่างอาจเป็นดังต่อไปนี้:

#include <iostream>
#include <map>

using namespace std;

int main()
{
        map<int, char> A;
        A[1] = 'b';
        A[3] = 'c';

        const map<int, char> B = A;

        cout << B.at(3) << endl; // it works
        cout << B[3] << endl;  // it does not work

}

สำหรับการใช้ "B [3]" จะแสดงข้อผิดพลาดต่อไปนี้ในระหว่างการคอมไพล์:

t01.cpp: 14: ข้อผิดพลาด: ส่งผ่าน 'const std :: map, std :: จัดสรร>>' เป็นอาร์กิวเมนต์ 'this' ของ '_Tp & std :: map <_Key, _Tp, _Compare, _Alloc> :: operator [] ( const _Key &) [with _Key = int, _Tp = char, _Compare = std :: less, _Alloc = std :: destroyator>] 'ทิ้งคุณสมบัติ

คอมไพเลอร์ที่ใช้คือ g ++ 4.2.1

คำตอบ:


127

at()เป็นวิธีการใหม่สำหรับstd::mapใน C ++ 11

แทนที่จะแทรกองค์ประกอบที่สร้างขึ้นเริ่มต้นใหม่เช่นเดียวกับoperator[]หากไม่มีองค์ประกอบที่มีคีย์ที่กำหนดไว้มันจะแสดงstd::out_of_rangeข้อยกเว้น (ซึ่งคล้ายกับลักษณะการทำงานของat()for dequeand vector.)

เนื่องจากพฤติกรรมนี้จึงสมเหตุสมผลที่จะมีการconstโอเวอร์โหลดซึ่งat()แตกต่างจากoperator[]ที่มีโอกาสเปลี่ยนแปลงแผนที่ได้เสมอ


เป็นไปได้ไหมที่จะให้ "at" ส่งคืนค่าเริ่มต้นแทนที่จะทิ้งข้อยกเว้น
user1202136

ฉันใช้at()กับ VS2013 ในโครงการที่ตั้งค่าให้ใช้ชุดเครื่องมือ VS2010 ฉันคิดว่านั่นหมายความว่าฉันไม่ได้ใช้ C ++ 11 ... แต่มันยังรวบรวม ... ??
thomthom

1
ฉันแค่ต้องแสดงความคิดเห็นว่ามันไม่สมเหตุสมผลที่จะละเว้นตัวดำเนินการ const [] ซึ่งอาจทำให้เกิดข้อยกเว้นสำหรับองค์ประกอบที่ไม่ได้แมปแทนที่จะเปลี่ยนแผนที่
Spencer

@Spencer มันจะน่าแปลกใจถ้า const และ non-const โอเวอร์โหลดของตัวดำเนินการ [] มีผลต่างกัน โดยปกติเราคาดหวังว่าหากมีการสร้างอ็อบเจกต์หรือการอ้างอิงที่ไม่ใช่ const ในโปรแกรม const โปรแกรมจะยังคงทำงานในลักษณะเดียวกันตราบเท่าที่คอมไพล์ การอนุญาตให้โอเวอร์โหลดที่ไม่ใช่ const เท่านั้นที่จะส่งข้อยกเว้นอาจทำให้เกิดข้อบกพร่องที่ไม่ถูกจับจนกว่าจะรัน
Brian

@ ไบรอันคุณหมายถึงการพูดว่า "อนุญาตให้เฉพาะconst overload เท่านั้นที่จะทิ้งข้อยกเว้น"?
Spencer

33

หากเป็นองค์ประกอบที่ไม่ได้อยู่ในmapที่operator []จะเพิ่ม - ซึ่งเห็นได้ชัดว่าไม่สามารถทำงานในconstแผนที่เพื่อ c ++ ไม่กำหนดconstรุ่นของผู้ประกอบการ นี่เป็นตัวอย่างที่ดีของตัวตรวจสอบประเภทของคอมไพเลอร์ที่ป้องกันข้อผิดพลาดรันไทม์ที่อาจเกิดขึ้น

ในกรณีของคุณคุณจำเป็นต้องใช้findแทนซึ่งจะมีเพียงกลับ (iterator ไป) mapองค์ประกอบถ้ามีอยู่ก็จะไม่ปรับเปลี่ยน หากรายการไม่ได้อยู่ก็จะส่งกลับไป iterator end()ของแผนที่

atไม่มีอยู่จริงและไม่ควรคอมไพล์ด้วยซ้ำ บางทีนี่อาจเป็น“ ส่วนขยายของคอมไพเลอร์” (=แมลง ใหม่ใน C ++ 0x)


มาตรฐาน C ++ ห้ามการใช้งานจากการกำหนดฟังก์ชันสมาชิกที่ไม่ได้มาตรฐานเพิ่มเติมในคลาสไลบรารีหรือไม่
Tim Martin

@ ทิมฉันเชื่อว่าอินเทอร์เฟซได้รับการแก้ไขแล้วใช่
Konrad Rudolph

4

[] - ผู้ดำเนินการจะสร้างรายการใหม่ในแผนที่หากไม่มีคีย์ที่ระบุ จึงอาจเปลี่ยนแผนที่

ดูลิงค์นี้.


2

สิ่งนี้ค่อนข้างแปลกใจสำหรับฉัน แต่แผนที่ STL ไม่มีตัวconstดำเนินการดัชนี นั่นคือB[3]ไม่สามารถอ่านอย่างเดียว จากคู่มือ:

เนื่องจากโอเปอเรเตอร์ [] อาจแทรกองค์ประกอบใหม่ลงในแผนที่จึงไม่สามารถเป็นฟังก์ชันสมาชิก const ได้

at()ฉันมีความคิดเกี่ยวกับการไม่มี

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