Pemahaman saya adalah bahwa dalam C ++ 11, ketika Anda mengembalikan variabel lokal dari suatu fungsi dengan nilai, kompiler diperbolehkan untuk memperlakukan variabel itu sebagai r-nilai referensi dan 'memindahkannya keluar dari fungsi untuk mengembalikannya (jika RVO / NRVO tidak terjadi sebagai gantinya, tentu saja).
Pertanyaan saya adalah, tidak bisakah ini memecahkan kode yang ada?
Pertimbangkan kode berikut:
#include <iostream>
#include <string>
struct bar
{
bar(const std::string& str) : _str(str) {}
bar(const bar&) = delete;
bar(bar&& other) : _str(std::move(other._str)) {other._str = "Stolen";}
void print() {std::cout << _str << std::endl;}
std::string _str;
};
struct foo
{
foo(bar& b) : _b(b) {}
~foo() {_b.print();}
bar& _b;
};
bar foobar()
{
bar b("Hello, World!");
foo f(b);
return std::move(b);
}
int main()
{
foobar();
return EXIT_SUCCESS;
}
Pikiranku adalah bahwa akan mungkin bagi penghancur objek lokal untuk referensi objek yang secara implisit dipindahkan, dan karena itu secara tak terduga melihat objek 'kosong'. Saya mencoba menguji ini (lihat http://ideone.com/ZURoeT ), tetapi saya mendapatkan hasil 'benar' tanpa eksplisit std::move
dalam foobar()
. Saya menduga itu karena NRVO, tetapi saya tidak mencoba mengatur ulang kode untuk menonaktifkannya.
Apakah saya benar karena transformasi ini (menyebabkan perpindahan fungsi) terjadi secara implisit dan dapat memecah kode yang ada?
PEMBARUAN Berikut adalah contoh yang menggambarkan apa yang saya bicarakan. Dua tautan berikut adalah untuk kode yang sama. http://ideone.com/4GFIRu - C ++ 03 http://ideone.com/FcL2Xj - C ++ 11
Jika Anda melihat outputnya, itu berbeda.
Jadi, saya kira pertanyaan ini sekarang menjadi, apakah ini dipertimbangkan ketika menambahkan langkah implisit ke standar, dan diputuskan bahwa tidak apa-apa untuk menambahkan perubahan ini karena kode semacam ini cukup langka? Saya juga bertanya-tanya apakah ada kompiler akan memperingatkan dalam kasus-kasus seperti ini ...