2010-05-13 30 views
9

Tôi muốn có được giá trị tiếp theo cho thiết bị lặp STL list nhưng nó không thực hiện operator+, vector. Tại sao và làm cách nào tôi có thể nhận được giá trị mà tôi muốn?Tại sao chỉ ngẫu nhiên truy cập-iterator thực hiện operator + trong C++?

Tôi nghĩ rằng tôi có thể làm điều đó nếu tôi gọi operator++ nhiều lần, nhưng không phải là một chút bẩn?

Những gì tôi muốn làm là như sau:

list<int> l; 
...omitted... 
list<int>::iterator itr = l.begin() + 3; // but, list iterator does not have 
             // operator+ 

giải pháp tốt nhất cho những gì tôi muốn là gì?

+2

(Hầu như) không liên quan: bạn cần đảm bảo rằng có thể đạt được vị trí này, nếu không bạn sẽ gọi hành vi không xác định. Mặc dù từ danh sách :: begin() 'thật dễ dàng, trong một trường hợp tổng quát hơn, cách duy nhất để biết (đối với nonAccessAccessIterator) khoảng cách với' list :: end() 'là gọi' std :: khoảng cách' ... O (N) quá. –

+0

Hai câu trả lời tuyệt vời về chủ đề này. +1 cho cộng đồng! –

Trả lời

17

Bạn cũng có thể sử dụng std::next (và trước) hoặc các giá trị tương đương do Boost cung cấp nếu bạn không có quyền truy cập vào C++ 11.

list<int>::iterator itr = std::next(l.begin(), 3); 

Lý do: std::advance là vụng về để sử dụng (nó hoạt động bằng cách tác dụng phụ, không bằng cách trả lại một bản sao).

+2

Điều đó rất hữu ích. Tôi luôn tự hỏi tại sao 'std :: advance' làm việc theo tác dụng phụ thay vì chức năng. –

+1

@RSam: Tôi đã luôn luôn giả định đó là vì 'std :: advance' có nghĩa là bắt chướC++ itr hoặc operator + =, nếu thích hợp. Các thuật toán Iterator thường được viết theo các thuật ngữ này, do đó, chúng đóng gói chúng có ý nghĩa nhất. –

+0

Nếu bạn muốn có một bản sao, bạn phải tự tạo một bản sao. Đây là trường hợp phổ biến trong C++. – mschneider

37

Bạn muốn sử dụng std::advance:

list<int>::iterator itr = l.begin(); 
std::advance(itr, 3); 

advance sẽ sử dụng operator+ và đầy đủ trong thời gian liên tục nếu iterator là truy cập ngẫu nhiên trong khi nó sẽ lặp trên operator++ và đầy đủ trong thời gian tuyến tính nếu lặp không phải là truy cập ngẫu nhiên .  

Lý do cho việc này là cung cấp cho bạn quyền kiểm soát các yêu cầu phức tạp. Nếu bạn quan tâm đến sự phức tạp của hoạt động của bạn, bạn sử dụng operator+ và nhận được thời gian liên tục nhưng điều này chỉ biên dịch với các trình vòng lặp truy cập ngẫu nhiên. Nếu bạn không quan tâm đến sự phức tạp, bạn sử dụng std::advance sẽ luôn hoạt động nhưng độ phức tạp sẽ thay đổi dựa trên trình lặp.

+3

+1 đơn giản, rõ ràng và kỹ lưỡng. – wilhelmtell

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