auto
có thể hỗ trợ hiệu suất bằng cách tránh chuyển đổi ngầm im lặng . Một ví dụ tôi thấy hấp dẫn là như sau.
std::map<Key, Val> m;
// ...
for (std::pair<Key, Val> const& item : m) {
// do stuff
}
Thấy lỗi không? Chúng tôi đang ở đây, nghĩ rằng chúng tôi thanh lịch lấy mọi vật phẩm trên bản đồ bằng cách tham chiếu và sử dụng biểu thức phạm vi mới để làm rõ ý định của chúng tôi, nhưng thực sự chúng tôi đang sao chép mọi yếu tố. Điều này là do std::map<Key, Val>::value_type
là std::pair<const Key, Val>
, không phải std::pair<Key, Val>
. Do đó, khi chúng tôi (ngầm) có:
std::pair<Key, Val> const& item = *iter;
Thay vì lấy một tham chiếu đến một đối tượng hiện có và để nó ở đó, chúng ta phải thực hiện chuyển đổi loại. Bạn được phép lấy tham chiếu const đến một đối tượng (hoặc tạm thời) thuộc loại khác miễn là có sẵn một chuyển đổi ngầm định, ví dụ:
int const& i = 2.0; // perfectly OK
Chuyển đổi loại là một chuyển đổi ngầm định được phép với cùng lý do bạn có thể chuyển đổi a const Key
thành a Key
, nhưng chúng tôi phải xây dựng tạm thời loại mới để cho phép điều đó. Do đó, vòng lặp của chúng tôi có hiệu quả:
std::pair<Key, Val> __tmp = *iter; // construct a temporary of the correct type
std::pair<Key, Val> const& item = __tmp; // then, take a reference to it
(Tất nhiên, thực tế không có một __tmp
đối tượng, nó chỉ ở đó để minh họa, trong thực tế, tạm thời không tên chỉ bị ràng buộc item
trong suốt cuộc đời của nó).
Chỉ cần thay đổi thành:
for (auto const& item : m) {
// do stuff
}
chỉ lưu cho chúng tôi một tấn bản sao - bây giờ loại được tham chiếu phù hợp với loại trình khởi tạo, do đó không cần tạm thời hoặc chuyển đổi, chúng tôi chỉ có thể thực hiện tham chiếu trực tiếp.