2010-10-13 42 views
18

Trong C++ 11 bây giờ chúng tôi có thể làm:Có C++ 11 cho vòng lặp cho phép tối ưu hóa mới hoặc tốt hơn?

void dosomething(std::vector<Thing>& things) 
{ 
    for(Thing& thing : things) 
    { 
     dofoo(thing); 
     wiizzz(thing); 
     tadaa(thing); 
    } 

} 

Tôi biết rằng việc bổ sung và sử dụng lambda là cú pháp đường nhưng nó cung cấp cơ hội tối ưu hóa thú vị.

Còn vòng lặp for thì sao? Nó chỉ là cú pháp cú pháp hoặc trình biên dịch có thể tối ưu hóa một số trường hợp mà nó không thể hoặc sẽ là quá khó để làm với vòng viết tay?

+0

Có 'for (Thing & thing: things)' trong C++ 0x chỉ định một thứ tự? hoặc có thể 'điều' xuất hiện theo thứ tự nào? – Inverse

+2

Nó chỉ lấy iterator từ thành viên begin() của container đã cho (nếu nó là một lớp) và lặp lại cho đến khi nó đạt đến trình kết thúc() iterator. Vì vậy, nó phụ thuộc vào vòng lặp hoặc phụ thuộc vào vùng chứa nếu bạn muốn. Trong trường hợp của một mảng thô (hoặc mảng ngữ nghĩa lớp quá?) Nó sẽ chỉ đi từ một [0] và kết thúc khi nó nhận được đến một [kích thước]. – Klaim

Trả lời

21

Nó chỉ là một đường cú pháp từ tiêu chuẩn nói rằng nó tương đương với một vòng lặp với vòng lặp [Sửa: điều này có nghĩa nó không cung cấp bất kỳ thông tin bổ sung cho các trình biên dịch so với tương đương cho vòng lặp — cuối chỉnh sửa ]. Bạn có thể có được một hiệu suất tốt hơn mặc dù vì nó tương đương với:

for(auto iter = con.begin(), end = con.end(); iter != end; ++iter) 
{ 
    auto& ref = *iter; 
    // ... 
} 

trong khi hầu hết mọi người có thể viết:

for(auto iter = con.begin(); iter != con.end(); iter++) 
{ 
    // use *iter directly 
    // ... 
} 

mà có thể chậm hơn nếu con.end(), ++ iter hoặc * ITER không không đáng kể.

[Sửa:

lambda là cú pháp đường

Không thực sự. Không giống như vòng lặp, nó cho phép trình biên dịch nắm bắt trực tiếp con trỏ cơ sở khung, đối với các biến được thu thập bằng tham chiếu, điều này giúp tiết kiệm một địa chỉ cho mỗi lần sử dụng, so với đối tượng hàm thủ công. — chỉnh sửa cuối]

+0

Bạn có chắc nó lưu trữ 'end()'? Điều này có nghĩa là bạn không thể thay đổi bộ sưu tập có ngữ nghĩa khác nhau (đối với các bộ sưu tập không làm mất hiệu lực trình vòng lặp khi chèn/xóa, ví dụ: 'danh sách'). – Motti

+0

Tôi đoán nó giả định rằng các container sẽ không thay đổi. Nếu nó sẽ, sử dụng thuật toán stl có thể là một cách tốt hơn. – Klaim

+3

@Motti: tiêu chuẩn nói rõ ràng rằng nó tương đương với mã trên (tốt, một chút phức tạp hơn bởi vì nó được phân biệt về phạm vi). Dù sao nếu vùng chứa của bạn không làm mất hiệu lực các trình vòng lặp, thì kết thúc() không phải là vô hiệu. Vậy vấn đề là gì? Bạn có thể thay đổi vùng chứa miễn là bạn không phá vỡ mã này. – ybungalobill

5

Có thể, nhưng có thể không. Nó loại bỏ khả năng tạo ra một biến chỉ số/truy cập sẽ không được sử dụng. Đó không phải là cũng yêu cầu cho vòng lặp bình thường, nhưng có nhiều khả năng xảy ra hơn chỉ vì đó là điều mà một số người quen làm.

Thực tế, có thể không tạo ra bất kỳ sự khác biệt nào ngay cả từ đó. Ít nhất, tôi thấy khó có thể tưởng tượng được một đội ngũ biên dịch quá tinh vi đến nỗi họ thậm chí có khát vọng nhỏ nhất để hỗ trợ C++ 0x, điều đó chưa xử lý điểm tầm thường tương đối để phát hiện và loại bỏ việc tạo và tăng chỉ số vòng lặp không bao giờ được sử dụng.

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