Почему std :: move предотвращает RVO?

Во многих случаях при возврате локального из функции, RVO вступает в силу. Однако я думал, что явно используяstd::move по крайней мере, принудительное перемещение, когда RVO не происходит, но это RVO все еще применяется, когда это возможно. Однако, похоже, что это не так.

#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 и GCC 4.71, отладка и выпуск (-O2) конфиг. Копия ctor никогда не вызывается. Ctor перемещения вызывается только VC ++ 11 в конфигурации отладки. На самом деле, с этими компиляторами все в порядке, но, насколько мне известно, RVO не является обязательным.

Однако, если я явно используюmove:

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

ход ctor всегда вызывается. Поэтому попытка сделать его «безопасным» делает его еще хуже.

Мои вопросы:
- Почемуstd::move предотвратить РВО?
- Когда лучше «надеяться на лучшее» и полагаться на RVO, и когда я должен явно использоватьstd::move? Или, другими словами, как я могу позволить оптимизации компилятора выполнять свою работу и по-прежнему обеспечивать перемещение, если RVO не применяется?

Ответы на вопрос(2)

Ваш ответ на вопрос