Có một vài tùy chọn mà tôi có thể nghĩ, mỗi tùy chọn đều có sự xấu xa của riêng mình.
Một tùy chọn hiển nhiên là sử dụng con trỏ (có thể là unique_ptr
) thay vì tham chiếu. Tất nhiên, để làm việc này, nó hoặc là yêu cầu phân bổ từ heap, hoặc phân bổ tùy chỉnh. Tôi nghĩ với một người phân bổ tốt, cách tiếp cận này có một số thành tích. Sau đó, một lần nữa, các nhà điều hành quá tải sẽ chỉ nhận được khó chịu.
Cách tiếp cận khác là lưu trữ biểu thức con theo giá trị thay vì tham chiếu const. Hiệu quả của phương pháp này phụ thuộc rất nhiều vào trình biên dịch, nhưng vì cơ bản bạn đang xử lý một loạt các thời gian, tôi sẽ tưởng tượng rằng các trình biên dịch hiện đại có thể tối ưu hóa các bản sao (hoặc ít nhất, nhiều bản sao).
Cách tiếp cận cuối cùng cho phép bạn giữ cùng cấu trúc với mã của mình, nhưng buộc người dùng đánh giá biểu thức. Nó yêu cầu bạn chỉ có một loại có thể lặp lại, là kiểu cơ bản của biểu thức (ví dụ: std::vector<int>
). Không có lớp biểu thức nào có các phương thức hoặc hàm begin
và end
được định nghĩa cho chúng, nhưng chỉ nên chuyển đổi thành loại cơ bản. Bằng cách này, mã như for(auto x : expr)
sẽ không thành công tại thời điểm biên dịch (vì expr
không thể lặp lại), nhưng viết for(auto x : static_cast<vector<int>>(expr))
hoạt động vì biểu thức đã được đánh giá.
Nếu bạn đang hy vọng sử dụng phạm vi dựa trên các vòng để thực hiện các phép toán biểu mẫu, thì bạn có thể cung cấp các phương thức riêng tư hoặc được bảo vệ begin
và end
trong các lớp mẫu biểu thức của bạn. Chỉ cần đảm bảo mỗi lớp mẫu có thể truy cập các phương thức begin
và end
của các lớp mẫu khác. Sẽ không sao trong ngữ cảnh này vì khuôn mẫu biểu thức là một tham số cho hàm, do đó bạn sẽ không phải lo lắng về việc tham khảo các tham chiếu khi viết vòng lặp trong hàm đó.
Nguồn
2012-03-07 07:42:05
'tự động &' trong phạm vi 'for' loop có thể thực sự trở thành một cái gì đó để tự bắn vào chân một cách dễ dàng - tôi vẫn chưa thực sự hiểu chính xác loại phạm vi nào bị ảnh hưởng và tại sao (tham chiếu lvalue để không-const: nguy hiểm, không tham khảo: unproblematic, ???). – Philipp
@Philipp: Không có thứ như "loại phạm vi". Có những loại đơn giản phù hợp với phạm vi "khái niệm". Cụ thể, có một cặp 'begin/end' ghi đè các trình vòng lặp đầu vào trả về. –
Tôi đoán câu trả lời là đảm bảo các mẫu biểu thức không phù hợp với phạm vi "khái niệm", tức là chúng không có 'bắt đầu' và' kết thúc'. – Clinton