Böyle uzun bir soru için özür dilerim ama mümkün olduğunca açık olmaya çalışıyorum. Bu bir şekilde strings in C++ ile ilgili önceki soruyu izler. Ben NRDO güvenmeden, gereksiz bellek ayırma, olmadan bir işlevden std :: dize nasıl dönebileceğini anlamaya çalışıyorum. Ben NRVO güvenmek istemiyorum nedenleri şunlardır:STL takas dönüşü mü?
biz şu anda her zaman hata ayıklama modunda etkin olmayabilir desteklenmektedir bile- o
si (... ne yazık ki, böylece hiçbir C++ 0x rvalue referanslar)
Ben C++ 03 uyumlu bir çözüm gerektiğini unutmayın bazı durumlarda (example) başarısını etkiler dediklerim mplest by-referans-pass ve bu
void test(std::string& res)
{
std::string s;
//...
res.swap(s);
}
gibi std :: takas yapmak Ama başarmak istiyorum ne yani, referans olarak geçmektedir olmadığı kadar değeriyle dönmek için daha doğal ve genellikle daha uygundur
std::string test()
{
std::string s;
//...
return SOMETHING(s);
}
İdeal sadece "dönüş değeri" ile swap
yapacağını ama C++ bunun nasıl görmüyorum: budur. Kopyalama yerine hareket eden zaten auto_ptr var ve ben aslında auto_ptr<string>
kullanabilirdim, ancak dize nesnesinin kendisini dinamik olarak ayırmaktan kaçınmak isterim.
Benim fikrim, bir kopya yapıcısı geri döndüğünde çağrıldığında, taşını taşımak için bir işlevden döndürülen bir dize nesnesini bir şekilde "etiketlemektir". Ya Kaçırdığım bazı ciddi sorunlar tüm bu mantıklı
struct Str
{
struct Moveable
{
Str & ref;
explicit Moveable(Str & other): ref(other) {}
};
Str() {}
Str(const std::string& other) : data(other) {} // copy
Str(Moveable& other) { data.swap(other.ref.data); } // move
Moveable Move()
{
return Moveable(*this);
}
std::string data;
};
Str test()
{
Str s;
//...
return s.Move(); // no allocation, even without NRVO
}
Yani ... neden olur mu: Ben ne istiyorum tam olarak işlevi gören bu kod ile sona erdi? (Örneğin, ömür boyu bir sorun olup olmadığından emin değilim). Belki de zaten böyle bir fikri kütüphanede (kitap, makale ...) gördünüz ve bana bir referans verebilir misiniz?
DÜZENLEME: As @ rstevens fark edildi, bu kod MSVC'ye özgüdür ve const olmayan geçici olmayanlar gibi g ++ altında derlenmez. Bu , bir sorundur, ancak bu uygulamanın yalnızca MSVC'ye özgü olduğunu varsayalım.
Ne sorduğundan emin değilim. Sadece kodunuzu düzeltmeniz gerekiyor mu? Tam olarak istediğini yaptığını söylüyorsun, ama - görebildiğim kadarıyla - derlememeli. –
Dizeninizin COW olup olmadığını kontrol ettiniz mi? Eğer öyleyse, fazladan bellek ayırmaları olacaktır. Ayrıca std :: string'in bazı uygulamaları dizgiyi nesneye (dizge kısa olduğunda) yerleştirir, bunun yerine bellek ayırır. Bunların doğruluğu doğruysa, optimizasyon girişimleriniz azaltmaktan ziyade maliyeti artırabilir. –
@Charles: Kod, neyi başarmaya çalıştığımı açıklamak için var, ve eğer doğru görüp görmediğimde ve eğer bunun iyi bir şekilde uygulanması durumunda soru. –