Các range-based for loop tương đương với:
{
init-statement
auto && __range = range_expression ;
...
}
Đối range_expression của bạn, nó sẽ là
auto && __range = *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5}));
Nhưng
Nếu range_expression trả về một tạm thời, tuổi thọ của pin được kéo dài cho đến khi kết thúc vòng lặp, như được chỉ ra bằng cách gắn vào các tài liệu tham khảo rvalue __range
, nhưng hãy cẩn thận rằng tuổi thọ của bất kỳ tạm thời trong vòng range_expression không được gia hạn.
Trả lại số std::make_unique
trả về là tạm thời std::unique_ptr
, sau khi biểu hiện đầy đủ, nó sẽ bị hủy. Điều đó có nghĩa là std::vector
được quản lý bởi nó cũng sẽ bị hủy; mặc dù số std::vector
nhận được từ số std::unique_ptr
tạm thời bị ràng buộc với tham chiếu chuyển tiếp, thời gian tồn tại của nó sẽ không được kéo dài.
Từ C++ 20 bạn có thể làm việc xung quanh bằng cách sử dụng init-statement; chẳng hạn như
for (auto p = std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5})); auto it : *p)
std::cout << it << std::endl;
Lưu ý rằng C++ 20 cho phép tránh loại lỗ hổng này thông qua "Phạm vi dựa trên câu lệnh với bộ khởi tạo", như được mô tả tại đây: https://herbsutter.com/2017/11/11/ trip-report-fall-iso-c-standards-meeting-albuquerque /. Tức là: bạn sẽ khai báo riêng biệt 'unique_ptr', đảm bảo nó tồn tại cho toàn bộ vòng lặp, sau đó sử dụng dereference của nó làm phạm vi để lặp lại. –
Tại sao không chỉ đơn giản là viết 'cho (tự động nó: {1, 2, 3, 4, 5})'? và đối với các trường hợp phức tạp hơn, tại sao có 'std :: unique_ptr>' thay vì 'std :: vector '. –
Jarod42
Vâng, đó là một ví dụ rất giả tạo, thể hiện khu vực có vấn đề nhưng theo một cách phóng đại. :) –