Trình biên dịch có thể tối ưu hóa giá trị thứ hai thành giá trị đầu tiên, nhưng giả định rằng hai giá trị này tương đương, tức là kết thúc() thực sự là không đổi. Một vấn đề có vấn đề hơn một chút là trình biên dịch có thể không thể suy ra rằng trình lặp kết thúc là hằng số do có thể có răng cưa. Tuy nhiên, giả sử rằng lời gọi kết thúc() được gạch chân, sự khác biệt chỉ là tải bộ nhớ.
Lưu ý rằng điều này giả định rằng trình tối ưu hóa được bật. Nếu trình tối ưu hóa không được kích hoạt, như thường được thực hiện trong các bản dựng gỡ lỗi, thì công thức thứ hai sẽ liên quan đến các cuộc gọi hàm N-1. Trong các phiên bản hiện tại của Visual C++, các bản dựng gỡ lỗi cũng sẽ phát sinh các lần truy cập bổ sung do chức năng kiểm tra prolog/epilog và các trình lặp gỡ lỗi nặng hơn. Vì vậy, trong mã nặng STL, mặc định cho trường hợp đầu tiên có thể ngăn chặn mã không bị chậm tương đối trong các bản dựng gỡ lỗi.
Chèn và loại bỏ trong vòng lặp là một khả năng, như những người khác đã chỉ ra, nhưng với kiểu vòng lặp này, tôi thấy khó xảy ra. Đối với một điều, các thùng chứa dựa trên nút - danh sách, tập hợp, ánh xạ - không làm mất hiệu lực kết thúc() trên một trong hai thao tác. Thứ hai, tăng iterator thường xuyên đã được di chuyển trong vòng lặp để tránh các vấn đề huỷ bỏ hiệu lực:
// assuming list -- cannot cache end() for vector
iterator it(c.begin()), end(c.end());
while(it != end) {
if (should_remove(*it))
it = c.erase(it);
else
++it;
}
Vì vậy, tôi xem xét một vòng lặp mà tuyên bố để gọi end() vì lý do đột biến-trong-loop và vẫn có ++ nó trong tiêu đề vòng lặp để nghi ngờ.
Nguồn
2009-04-28 22:30:50
Việc khai báo 'ite' sẽ là lỗi cú pháp nên phiên bản đầu tiên của bạn trở thành "cho (const_iterator i = list.begin(), e = list.end(); i! = E; ++ i)". Đây chỉ là một vài ký tự hơn so với hình thức thứ hai, vì vậy tôi chỉ sử dụng nó theo mặc định. – Bklyn
Bây giờ trong C++ 11 cũng có 'cho (tự động nó: danh sách)' mà về cơ bản là thứ hai. Nhưng đẹp hơn rất nhiều. – Cramer
@Cramer phạm vi dựa trên vòng lặp trên các phần tử, không phải vị trí vòng lặp, vì vậy tương đương là 'cho (const auto & element: list)' – boycy