Anladığım kadarıyla, C ++ 11'de, bir işlevden değere göre yerel bir değişken döndürdüğünüzde, derleyicinin bu değişkeni bir r değeri başvurusu olarak kabul etmesine ve döndürmek için işlevden 'taşımasına' izin verilir. Bunun yerine RVO / NRVO gerçekleşmez).
Benim sorum şu, bu mevcut kodu kıramaz mı?
Aşağıdaki kodu göz önünde bulundurun:
#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;
}
Düşüncelerim, yerel bir nesnenin yıkıcısının, dolaylı olarak taşınan nesneye referans vermesinin ve dolayısıyla beklenmedik bir şekilde 'boş' bir nesneyi görmesinin mümkün olacağıydı. Ben (bkz Bunu test etmeye çalıştı http://ideone.com/ZURoeT ), ama açık olmadan 'doğru' sonucu aldığım std::move
in foobar()
. NRVO nedeniyle olduğunu tahmin ediyorum, ama bunu devre dışı bırakmak için kodu yeniden düzenlemeye çalışmadım.
Bu dönüşümün (işlevden çıkmasına neden olan) dolaylı olarak gerçekleşmesi ve var olan kodu kırabilmesinde doğru muyum?
GÜNCELLEME İşte neden bahsettiğimi gösteren bir örnek. Aşağıdaki iki bağlantı aynı kod içindir. http://ideone.com/4GFIRu - C ++ 03 http://ideone.com/FcL2Xj - C ++ 11
Çıktıya bakarsanız, farklıdır.
Yani, sanırım şimdi bu soru haline geldi, bu standarda örtülü hareket eklenirken dikkate alındı ve bu tür bir kod yeterince nadir olduğu için bu kırılma değişikliğini eklemenin tamam olduğuna karar verildi mi? Bu tür durumlarda herhangi bir derleyicinin uyarıp uyarmayacağını merak ediyorum ...