auto
dapat membantu kinerja dengan menghindari konversi tersirat diam . Contoh yang saya temukan menarik adalah sebagai berikut.
std::map<Key, Val> m;
// ...
for (std::pair<Key, Val> const& item : m) {
// do stuff
}
Lihat bugnya? Kita di sini, berpikir kita secara elegan mengambil setiap item di peta dengan referensi const dan menggunakan rentang-untuk ekspresi baru untuk memperjelas maksud kita, tetapi sebenarnya kita menyalin setiap elemen. Hal ini karena std::map<Key, Val>::value_type
ini std::pair<const Key, Val>
, tidak std::pair<Key, Val>
. Jadi, ketika kita (secara implisit) memiliki:
std::pair<Key, Val> const& item = *iter;
Alih-alih mengambil referensi ke objek yang ada dan membiarkannya, kita harus melakukan konversi jenis. Anda diizinkan untuk mengambil referensi const ke objek (atau sementara) dari jenis yang berbeda selama ada konversi tersirat yang tersedia, misalnya:
int const& i = 2.0; // perfectly OK
Konversi tipe adalah konversi implisit yang diizinkan untuk alasan yang sama Anda dapat mengonversi a const Key
menjadi Key
, tetapi kami harus membuat sementara dari tipe baru untuk memungkinkannya. Jadi, secara efektif loop kita tidak:
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
(Tentu saja, sebenarnya tidak ada __tmp
objek, itu hanya ada untuk ilustrasi, pada kenyataannya sementara yang tidak disebutkan namanya hanya terikat item
untuk seumur hidup).
Hanya mengubah ke:
for (auto const& item : m) {
// do stuff
}
baru saja menyelamatkan kami dari satu ton salinan - sekarang jenis yang direferensikan cocok dengan jenis penginisialisasi, jadi tidak ada sementara atau konversi diperlukan, kami hanya dapat melakukan referensi langsung.