Warum verhindert std :: move RVO?

In vielen Fällen, wenn ein Local von einer Funktion zurückgegeben wird, greift RVO ein. Ich dachte jedoch, dass dies explizit verwendet wirdstd::move würde zumindest das Verschieben erzwingen, wenn RVO nicht stattfindet, aber dieses RVO wird weiterhin angewendet, wenn dies möglich ist. Dies scheint jedoch nicht der Fall zu sein.

#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;
}

Ich habe diesen Code mit VC ++ 11 und GCC 4.71 getestet, debuggen und freigeben (-O2) config. Der Kopierer wird nie aufgerufen. Der move ctor wird nur von VC ++ 11 in der Debug-Konfiguration aufgerufen. Eigentlich scheint bei diesen Compilern alles in Ordnung zu sein, aber meines Wissens ist RVO optional.

Allerdings wenn ich das explizit benutzemove:

HeavyWeight MakeHeavy()
{
    HeavyWeight heavy;
    return std::move(heavy);
}

der move ctor wird immer aufgerufen. Der Versuch, es "sicher" zu machen, macht es noch schlimmer.

Meine Fragen sind:
- Warum tutstd::move RVO verhindern?
- Wann ist es besser, "auf das Beste zu hoffen" und sich auf RVO zu verlassen, und wann sollte ich dies ausdrücklich anwenden?std::move? Oder mit anderen Worten, wie kann ich die Compileroptimierung ihre Arbeit machen lassen und trotzdem verschieben, wenn RVO nicht angewendet wird?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage