Por que o std :: move impede o RVO?

Em muitos casos, ao retornar um local de uma função, o RVO entra em ação. No entanto, pensei que usar explicitamentestd::move pelo menos reforçaria a movimentação quando a RVO não acontece, mas a RVO ainda é aplicada quando possível. No entanto, parece que este não é o caso.

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

Eu testei este código com VC ++ 11 e GCC 4.71, depurar e liberar (-O2) config. O copiador nunca é chamado. O ctor de movimento é chamado apenas pelo VC ++ 11 em debug config. Na verdade, tudo parece estar bem com esses compiladores em particular, mas que eu saiba, o RVO é opcional.

No entanto, se eu usar explicitamentemove:

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

o diretor de movimento é sempre chamado. Então, tentar torná-lo "seguro" torna tudo pior.

Minhas perguntas são:
- Porquestd::move prevenir RVO?
- Quando é melhor "esperar pelo melhor" e confiar no RVO, e quando devo usar explicitamentestd::move? Ou, em outras palavras, como posso deixar a otimização do compilador funcionar e ainda impor a movimentação se a RVO não for aplicada?

questionAnswers(2)

yourAnswerToTheQuestion