Quyền truy cập phần tử bản đồ const trong C ++


100

Tôi đã cố gắng sử dụng toán tử [] truy cập phần tử trong bản đồ const C ++, nhưng phương pháp này không thành công. Tôi cũng đã cố gắng sử dụng "at ()" để làm điều tương tự. Lần này nó đã hoạt động. Tuy nhiên, tôi không thể tìm thấy bất kỳ tài liệu tham khảo nào về việc sử dụng "at ()" để truy cập phần tử trong bản đồ const C ++. "At ()" có phải là một hàm mới được thêm vào trong bản đồ C ++ không? Tôi có thể tìm thêm thông tin về điều này ở đâu? Cảm ơn rât nhiều!

Một ví dụ có thể là như sau:

#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

}

Đối với việc sử dụng "B [3]", nó trả về các lỗi sau trong quá trình biên dịch:

t01.cpp: 14: error: truyền 'const std :: map, std :: Distribator>>' làm đối số 'this' của '_Tp & std :: map <_Key, _Tp, _Compare, _Alloc> :: operator [] ( const _Key &) [với _Key = int, _Tp = char, _Compare = std :: less, _Alloc = std :: Distribator>] 'loại bỏ các định nghĩa

Trình biên dịch được sử dụng là g ++ 4.2.1

Câu trả lời:


124

at()là một phương thức mới std::maptrong C ++ 11.

Thay vì chèn một phần tử được xây dựng mặc định mới như operator[]thể một phần tử có khóa đã cho không tồn tại, nó sẽ ném ra một std::out_of_rangengoại lệ. (Điều này tương tự với hành vi của at()for dequevector.)

Do hành vi này có nghĩa là có constquá tải at(), không giống như operator[]luôn có khả năng thay đổi bản đồ.


Có thể có "at" trả về một giá trị mặc định thay vì ném một ngoại lệ?
user1202136

Tôi đang sử dụng at()với trong VS2013 trên một tập dự án để sử dụng bộ công cụ VS2010. Tôi nghĩ điều đó có nghĩa là tôi không sử dụng C ++ 11 ... Nhưng nó biên dịch ... ??
thomthom

1
Tôi chỉ cần nhận xét rằng không có ý nghĩa gì khi bỏ qua toán tử const [], điều này cũng có thể tạo ra một ngoại lệ cho một phần tử chưa được ánh xạ thay vì thay đổi bản đồ.
Spencer

@Spencer Sẽ rất ngạc nhiên nếu quá tải const và không phải const của toán tử [] có tác dụng khác nhau. Thông thường, chúng ta mong đợi rằng nếu một số đối tượng hoặc tham chiếu không phải là const trong một chương trình được tạo là const, chương trình sẽ tiếp tục hoạt động theo cách tương tự, miễn là nó biên dịch. Chỉ cho phép quá tải không const để ném các ngoại lệ có thể dẫn đến lỗi không được bắt cho đến thời gian chạy.
Brian

@Brian Có phải bạn muốn nói "Chỉ cho phép quá tải const để đưa ra các ngoại lệ"?
Spencer

33

Nếu một phần tử không tồn tại trong a map, thì operator []sẽ thêm nó vào - điều này rõ ràng là không thể hoạt động trong một constbản đồ nên C ++ không xác định constphiên bản của toán tử. Đây là một ví dụ hay về trình kiểm tra kiểu của trình biên dịch ngăn ngừa lỗi thời gian chạy tiềm ẩn.

Trong trường hợp của bạn, bạn cần sử dụng findthay vào đó sẽ chỉ trả về một phần tử (trình vòng lặp cho) nếu nó tồn tại, nó sẽ không bao giờ sửa đổi map. Nếu một mục không tồn tại, nó sẽ trả về một trình vòng lặp cho bản đồ end().

atkhông tồn tại và thậm chí không nên biên dịch. Có lẽ đây là một “phần mở rộng của trình biên dịch” (=một lỗi mới trong C ++ 0x).


Chuẩn C ++ có cấm việc triển khai xác định các hàm thành viên bổ sung không chuẩn trong các lớp thư viện không?
Tim Martin

@Tim Tôi tin rằng giao diện đã được sửa, vâng.
Konrad Rudolph

4

Người điều hành [] sẽ tạo một mục mới trong bản đồ nếu khóa đã cho không tồn tại. Do đó, nó có thể thay đổi bản đồ.

Xem liên kết này .


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.