Birçok durumda, bir işlevden yerel bir yeri döndürürken, RVO devreye girer. Ancak, açık bir şekilde std::move
kullanılmasının RVO gerçekleşmediğinde harekete geçeceğini, ancak mümkün olduğunda RVO'nun hala uygulanacağını düşündüm. Ancak, durum böyle değil gibi görünüyor. std :: move neden RVO'yu engeller?
#include "iostream"
class HeavyWeight
{
public:
HeavyWeight()
{
std::cout << "ctor" << std::endl;
}
HeavyWeight(const HeavyWeight& other)
{
std::cout << "copy" << std::endl;
}
HeavyWeight(HeavyWeight&& other)
{
std::cout << "move" << std::endl;
}
};
HeavyWeight MakeHeavy()
{
HeavyWeight heavy;
return heavy;
}
int main()
{
auto heavy = MakeHeavy();
return 0;
}
VC++ 11 ve GCC 4.71, hatalarını bulması ve salma (
-O2
) yapılandırma ile bu kodu test edilmiştir. Kopya cetesi hiç çağrılmadı. Hareket ctor, hata ayıklama yapılandırmasında yalnızca VC++ 11 ile çağrılır. Aslında, özellikle bu derleyicilerle her şey iyi görünüyor, fakat bilgime göre, RVO isteğe bağlıdır.
Ancak, açıkça move
kullanıyorsanız:
HeavyWeight MakeHeavy()
{
HeavyWeight heavy;
return std::move(heavy);
}
hareket ctor daima
denir. Yani bunu "güvenli" yapmaya çalışmak onu daha da kötüleştiriyor.Sorularım şunlardır:
- Neden std::move
RVO'yu engelliyor?
- Ne zaman "en iyisini umuyorum" ve RVO'ya güvenmek daha iyidir ve ne zaman std::move
'u kullanmalıyım? Ya da başka bir deyişle, derleyici optimizasyonunun işini yapmasına nasıl izin verebilirim ve hala RVO uygulanmazsa harekete geçmeyi nasıl sağlayabilirim?
İnsanlar neden bu günlerde “en iyisi için umut” den bahsediyor? C++ 11 desteğini kullanan ancak RVO'yu düzgün bir şekilde kullanamayan ne tür bir derleyici kullanıyorlar? –
Kopyalama seçimi (RVO'nun arkasındaki mekanizma) yalnızca belirli koşullar altında izin verilir. Std :: move kelimesinin yazılması, bu koşulların yerine getirilmesini engeller. –
@KerrekSB Ve std :: move tarafından engellenen bu koşullar ...? – cdoubleplusgood