2015-07-09 13 views
6

Tôi đang tạo bản đồ chỉ dành cho mục đích học tập để lưu trữ một số cặp khóa giá trị. Nếu tôi in trường thứ hai của bản đồ bằng cách sử dụng chức năng begin() Tôi có thể in trường thứ hai của bản đồ nhưng khi tôi cố gắng làm tương tự với phần tử bản đồ cuối cùng bằng cách sử dụng end(), nó không thể in trường thứ hai. Dưới đây là mã của tôi:Không thể lấy trường thứ hai của bản đồ bằng cách sử dụng kết thúc()

#include <iostream> 
#include <cstdlib> 
#include <map> 
#include <string> 
#include <stdio.h> 


using namespace std; 

map<int,std::string> arr; 

map<int,std::string>::iterator p; 

int main(int argc, char** argv) { 

    arr[1] = "Hello"; 
    arr[2] = "Hi"; 
    arr[3] = "how"; 
    arr[4] = "are"; 
    arr[5] = "you"; 

    p = arr.begin(); 
    printf("%s\n",p->second.c_str()); 

    p = arr.end(); 
    printf("%s\n",p->second.c_str()); 

    return 0; 

} 
+3

cho hộp chứa STL, ".end()" mang lại một trình lặp cho "yếu tố 1 thành phần cuối" cũng xem: http: // stackoverflow.com/questions/15252002/what-is-the-past-the-end-iterator-in-stl-c – user2950911

Trả lời

2

Để in yếu tố cuối cùng, sử dụng reverse iterator:

map< int,std::string>::reverse_iterator p; 
p = arr.rbegin(); 
if(p != arr.rend()) { 
    // Do whatever with, it points to the last element 
} else { 
    // map is empty 
} 

std::map::end sẽ trả lại iterator một yếu tố cuối cùng trong quá khứ và dereferencing đó là hành vi không xác định.

Từ std::map::end tại en.cppreference

Trả về một iterator để yếu tố sau đây yếu tố cuối cùng của container. Phần tử này hoạt động như một trình giữ chỗ; cố gắng truy cập vào nó kết quả trong hành vi không xác định.

1

std :: SOMETHING.end() không trả lại yếu tố cuối cùng, nó sẽ trả về yếu tố quá khứ-the-end. Kiểm tra C++ documentation. Về bản chất những gì bạn đang làm là cố gắng để deference vị trí bộ nhớ không xác định.

6

Dereferencing end()undefined behaviorend() trả về trình lặp 1 đến cuối bản đồ. Nếu bạn muốn yếu tố cuối cùng thì bạn có thể sử dụng

p = --arr.end(); 

Bạn không thể sử dụng

p = arr.rbegin() 

Như bạn không thể gán một iterator ngược lại để một iterator về phía trước (live example). Nếu bạn muốn sử dụng rbegin() thì bạn phải tạo một trình lặp ngược lại.

map<int,std::string>::reverse_iterator rit; 
rit = arr.rbegin(); 

// or 

auto rit = arr.rebegin(); //C++11 or higher required for this 

Hoặc bạn có thể chuyển nó sang một iterator về phía trước sử dụng this answer bởi visitor

Như mọi khi, bạn nên kiểm tra để chắc chắn rằng bạn có một iterator hợp lệ. Nếu vùng chứa trống begin() == end() và dereferencing là hành vi không xác định.

Nguồn: http://en.cppreference.com/w/cpp/container/map/end

+1

"' begin() == end() '" - Tôi nghĩ 'arr.empty()' là rõ ràng hơn . Nó cũng có thể nhanh hơn. –

+0

@NO_NAME Tôi đã chỉ chứng minh rằng việc sử dụng 'begin()' là giống như 'end()' nếu vùng chứa trống. – NathanOliver

2

Bạn có thể sử dụng --arr.end() hoặc arr.rbegin().

arr.end() trả về trình lặp cho phần tử sau phần tử cuối cùng. Điều này cho phép các vòng viết dễ dàng hơn. Yếu tố này chỉ để so sánh. Dereferencing nó không được phép.

1

Như đã được chỉ ra trong các bài đăng khác end() là một vị trí một vòng lặp qua phần tử cuối cùng trong bản đồ. Vì vậy, bạn không nên cố gắng để có được các lĩnh vực của nó. Để có được phần tử cuối cùng, bạn có thể sử dụng rbegin().

Các vấn đề liên quan