Почему С++ не перемещает ссылки на rvalue по умолчанию?

Скажем, у меня есть следующая функция

void doWork(Widget && param)  // param is an LVALUE of RRef type
{
    Widget store = std::move(param); 
}

Зачем мне прикладывать param к rvalue с помощью std::move()? Разве не должно быть очевидно, что тип param является rvalue, поскольку он был объявлен в сигнатуре функции как ссылка rvalue? Не следует ли автоматически ссылаться на конструктор перемещения здесь только по этому принципу?

Почему это не происходит по умолчанию?

Ответ 1

с вашим дизайном:

void doWork(Widget && param)
{
    Widget store1 = param;     // automatically move param
    Widget store2 = param;     // boom

    Widget store_last = param; // boom    
}

с текущим дизайном:

void doWork(Widget && param)
{
    Widget store1 = param;                // ok, copy
    Widget store2 = param;                // ok, copy

    Widget store_last = std::move(param); // ok, param is moved at its last use
}

Итак, мораль здесь заключается в том, что даже если у вас есть ссылка rvalue, у вас есть имя для нее, что означает, что вы можете использовать ее несколько раз. Таким образом, вы не можете автоматически переместить его, потому что он может понадобиться для последующего использования.