İnş std geçen gün::parametre olarak string &?
const &
std::vector
std::string
geçmesine sebep büyük ölçüde gitmiş olduğunu öne süren Herb Sutter tarafından yapılan bir konuşma duydum. Aşağıdaki gibi bir fonksiyon yazma artık tercih olduğunu söyledi:
std::string do_something ( std::string inval )
{
std::string return_val;
// ... do stuff ...
return return_val;
}
return_val
işlev ve bu nedenle çok ucuz olan hareket semantiği kullanarak iade edilebilir noktada bir rvalue olacağını anlıyorum. Ancak, inval
hala bir başvuru genellikle bir işaretçi olarak uygulanır) boyutu çok daha büyük. Bu std::string
bir kısa dize optimizasyonu için yığın işaretçisi ve bir üyesi char[]
dahil olmak üzere çeşitli bileşenlere sahip olmasıdır. Başvuru geçerken hala iyi bir fikir gibi geliyor bana.
Herkes Ot söylemişti sanırım niçin bu olabilir mi?
CEVAP
Neden Ot ne dedi Bu gibi vakalar yüzünden olduğunu söyledi.
Hadi C
işlev B
, işlev çağrıları A
işlevi var. A
C
B
ile ve bir dize geçer. A
C
; A
bilir B
olduğunu biliyor umursamıyor. B
uygulama, C
.
Hadi aşağıdaki gibi tanımlandığını söylüyor
void A()
{
B("value");
}
Eğer B ve C const&
tarafından dize alırsak o zaman şöyle bir şey:
void B(const std::string &str)
{
C(str);
}
void C(const std::string &str)
{
//Do something with `str`. Does not store it.
}
Tüm iyi ve güzel. Sadece etrafında işaretçileri geçen sen, kopyalama, hareketli, herkes mutlu olur. C
dizesini depolamak değil çünkü const&
alır. Sadece kullanır.
Şimdi, basit bir değişiklik yapmak istiyorum: C
dize bir yerde saklamak gerekir.
void C(const std::string &str)
{
//Do something with `str`.
m_str = str;
}
Merhaba, kopya yapıcı ve potansiyel bellek ayırma (Short String Optimization (SSO) Yoksay). C semantik mümkün gereksiz kaldırmak için yapmak gereken 11 hareket kopyasını oluşturarak, değil mi? Ve A
geçici; C
için bir sebep yok geçerkopyalaverileri. Sadece verildi ne ile kaçmak gerekir.
Bunu bile yapamazsın. const&
alır çünkü.
Eğer C
değeri parametre almak değiştirirsem, o sadece B
Bu parametre içine kopyalayın neden olur; bunun bana hiçbir yararı olmaz.
Eğer tüm fonksiyonları ile değer str
geçti std::move
veri etrafında karıştırmak güvenmek olsaydı bu sorunu yaşamazdık. Eğer birisi onu elinde tutmak istiyorsa, olabilir. Eğer doğru değilse, oh iyi. onlar don eğer
Daha pahalı? Evet; bir değer haline hareket referanslar kullanmaktan daha pahalıdır. Kopya daha az pahalı? SSO ile küçük dizeleri için değil. Yapmaya değer mi?
Kullanma durumu bağlıdır. Ne kadar bellek ayırmalarını nefret ediyorsun?
özelliği bir işlevi string parametre o...
Geçen XAML komuta parametre olarak num...
Geçen JavaScript fonksiyonu parametre ...
Geçen ruby'de bir yöntemi parametre ol...
jQuery POST parametre olarak string gö...