Jawaban:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Ini mengembalikan referensi menggantung, seperti halnya dengan kasus referensi lvalue. Setelah fungsi kembali, objek sementara akan dihancurkan. Anda harus mengembalikan Beta_ab
berdasarkan nilainya, seperti berikut ini
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
Sekarang, itu benar memindahkan Beta_ab
objek sementara ke nilai kembali fungsi. Jika kompiler bisa, itu akan menghindari langkah sama sekali, dengan menggunakan RVO (optimasi nilai balik). Sekarang, Anda dapat melakukan hal berikut
Beta_ab ab = others.toAB();
Dan itu akan memindahkan konstruksi sementara ke ab
, atau melakukan RVO untuk menghilangkan melakukan gerakan atau menyalin sama sekali. Saya sarankan Anda membaca BoostCon09 Rvalue Referensi 101 yang menjelaskan masalah ini, dan bagaimana (N) RVO berinteraksi dengan ini.
Kasus Anda mengembalikan referensi nilai akan menjadi ide bagus di kesempatan lain. Bayangkan Anda memiliki getAB()
fungsi yang sering Anda panggil untuk sementara waktu. Tidak optimal untuk membuatnya mengembalikan referensi nilai konstan untuk nilai sementara. Anda dapat menerapkannya seperti ini
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Perhatikan bahwa move
dalam hal ini bukan opsional, karena ab
bukan merupakan nilai lokal otomatis atau sementara. Sekarang, ref-kualifikasi &&
mengatakan bahwa fungsi kedua dipanggil pada nilai sementara, membuat langkah berikut, alih-alih menyalin
Beta_ab ab = Beta().getAB();
Ini bisa lebih efisien, misalnya, dalam konteks yang sedikit berbeda:
template <typename T>
T&& min_(T&& a, T &&b) {
return std::move(a < b? a: b);
}
int main() {
const std::string s = min_(std::string("A"), std::string("B"));
fprintf(stderr, "min: %s\n", s.c_str());
return 0;
}
Sebagai pengamatan yang menarik, pada mesin saya clang++ -O3
menghasilkan 54 instruksi untuk kode di atas dibandingkan 62 instruksi untuk reguler std::min
. Namun, dengan -O0
itu menghasilkan 518 instruksi untuk kode di atas dibandingkan 481 untuk reguler std::min
.
for(:)
dan mengintegrasikan lebih dari objek yang tidak dialokasikan. Fix: ideone.com/tQVOal
std::move()
hanya digunakan sebagai pemeran eksplisit untuk menggambarkan poin lebih jelas. Ini bukan kode yang akan Anda salin-tempel ke proyek Anda. Itu tidak bertentangan dengan jawaban terpilih, karena ada objek sementara dibuat di dalam fungsi. Di sini objek yang dikembalikan adalah salah satu argumen (objek sementara dihancurkan sebagai langkah terakhir dalam mengevaluasi ekspresi penuh yang (secara leksikal) berisi titik di mana mereka dibuat).