Değere göre dönmelisiniz.
Standart, değere göre geri dönüş verimliliğini artırmak için belirli bir özelliğe sahiptir. Buna "kopya elizyonu" denir ve daha özel olarak bu durumda "adlandırılmış dönüş değeri optimizasyonu (NRVO)".
Derleyiciler uygulamak gerekmez, ama sonra tekrar derleyiciler yok olması inlining işlevi uygulamak için (ya da hiç bir optimizasyon gerçekleştirmek). Ancak, derleyiciler optimize etmezse ve tüm ciddi derleyiciler satır içi ve NRVO (ve diğer optimizasyonlar) uygularsa standart kitaplıkların performansı oldukça zayıf olabilir.
NRVO uygulandığında, aşağıdaki kodda herhangi bir kopyalama olmayacaktır:
std::vector<int> f() {
std::vector<int> result;
... populate the vector ...
return result;
}
std::vector<int> myvec = f();
Ancak kullanıcı bunu yapmak isteyebilir:
std::vector<int> myvec;
... some time later ...
myvec = f();
Kopyalama seçimi burada bir kopyayı engellemez çünkü bu bir başlatma değil atamadır. Ancak yine de değere göre dönmelisiniz. C ++ 11'de atama, "taşıma semantiği" adı verilen farklı bir şeyle optimize edilir. C ++ 03'te, yukarıdaki kod bir kopyaya neden olur ve teoride bir eniyileyici bundan kaçınabilir, ancak pratikte çok zordur. Yani myvec = f()
, C ++ 03 yerine şunu yazmalısınız:
std::vector<int> myvec;
... some time later ...
f().swap(myvec);
Kullanıcıya daha esnek bir arayüz sunmak olan başka bir seçenek daha var:
template <typename OutputIterator> void f(OutputIterator it) {
... write elements to the iterator like this ...
*it++ = 0;
*it++ = 1;
}
Bunun üzerine mevcut vektör tabanlı arayüzü de destekleyebilirsiniz:
std::vector<int> f() {
std::vector<int> result;
f(std::back_inserter(result));
return result;
}
Bu belki senin kod kullanımları mevcut ise, varolan kodun daha az verimli olması reserve()
ön sadece sabit bir miktardan daha fazla karmaşık bir şekilde. Ancak mevcut kodunuz temelde push_back
vektörü tekrar tekrar çağırıyorsa , o zaman bu şablon tabanlı kodun o kadar iyi olması gerekir.
f
?