2013-02-27 20 views
7

Tôi cần phải xóa một phần tử khỏi một số std::list sau khi tìm thấy nó với std::find. Hành vi gọi std::list::erase với số end() của danh sách là gì? trường hợp của tôi là một cái gì đó như thế này:Hành vi xóa `kết thúc()` của một `std :: list` là gì?

std::list<T> mylist; 
T value; 
std::list::iterator it = std::find(mylist.begin(), mylist.end(), value); 
std::list::iterator next = mylist.erase(it); 

cplusplus.com nói:

Nếu vị trí (hoặc phạm vi) là hợp lệ, chức năng không bao giờ ném (đảm bảo không ném) trường hợp ngoại lệ. Nếu không, nó gây ra hành vi không xác định.

nhưng những gì tôi không biết là liệu end() được coi là hợp lệ ở đó hay không.

+0

'end()' là một trong quá khứ phần tử cuối cùng. –

+0

cplusplus.com tương tự bên ngoài giới hạn của các nguồn có uy tín. Xem cppreference.com để thay thế. – Potatoswatter

+0

@Potatoswatter: Internet nằm ngoài giới hạn của các nguồn có uy tín. Xem đặc tả ngôn ngữ để thay thế. –

Trả lời

17

Trang web đó sử dụng cụm từ mơ hồ (và có thể cho là không chính xác) "hợp lệ", nhưng đặc tả thư viện (C++ 11 23.2.3) sử dụng thuật ngữ cụ thể hơn "dereferenceable" - nghĩa là trình lặp phải tham chiếu đến một đối tượng. Trình lặp cuối cùng không thể bỏ qua, vì vậy việc xóa nó cho hành vi không xác định.

+3

+1, tôi cũng nghĩ rằng web có vấn đề tồi tệ hơn là * mơ hồ *, vì 'valid' là một thuật ngữ được sử dụng trong tiêu chuẩn và' end() 'mang lại * hợp lệ * iterator (tức là trang web không * mơ hồ *, nó là ** sai **) –

+0

Thực ra, đặc tả thư viện cũng sử dụng "hợp lệ" (ví dụ để chèn, trong đó một 'end()' -Iterator là ok), nhưng nó nói rõ ràng "hợp lệ * và * dereferencable" như là một yêu cầu cho single-iterator-erase. –

+0

Cảm ơn! Đây là những gì tôi đang tìm kiếm. Tôi không có quyền truy cập vào đặc tả. Bạn có biết nếu nó là như nhau trong C++ 03? – Janoma

6

Nó không phải là. Đang cố gắng xóa end() kết quả trong hành vi không xác định.

2

end() Trả về một trình vòng lặp tham chiếu tới trình lặp vòng lặp trong suốt trong vùng chứa danh sách và không phải là đối tượng cuối cùng trong danh sách.

Bằng cách xóa/xóa kết thúc, bạn đang xóa bên ngoài phạm vi danh sách của mình. code của bạn nên là:

std::list<T> mylist; 
T value; 
std::list::iterator it = std::find(mylist.begin(), mylist.end(), value); 
If(it!=mylist.end()) 
    std::list::iterator next = mylist.erase(it); 

Ngoài ra nếu find() thất bại trong việc tìm một giá trị trong danh sách của bạn nó sẽ trả lại lặp kết thúc, nó là cơ bản nói với bạn rằng giá trị mà bạn đang tìm kiếm nằm ngoài danh sách của bạn (không có trong danh sách của bạn)

+0

Không có phần tử quá hạn trong vùng chứa. 'end()' trả về một trình lặp ** lặp lại **. Nói chung, một trình vòng lặp kết thúc không cần phải tham chiếu đến một phần tử, mặc dù trong nhiều tình huống trên thực tế nó có. –

+0

Đã sửa, không cần phải điên –

+0

Điên? Tôi hy vọng tôi đã không đi qua theo cách đó. –