Дорого для перемещения типов

Я читаю официальные CPPCoreGuidelines, чтобы правильно понимать, когда надежно рассчитывать на RVO, а когда нет. На F20 написано:

Если тип дорогой для перемещения (например, массив), рассмотрите выделяя его в свободном хранилище и возвращая дескриптор (например, unique_ptr) или передать его в ссылку на неконстантный целевой объект для заполнения (для использования в качестве выходного параметра)

Я понимаю, что типы не-STL не оптимизированы для перемещения, но как я могу легко обнаружить другие типы, которые нужно переместить, поэтому я не буду использовать RVO для них?

Ответ 1

Вы, кажется, неправильно поняли, что такое "RVO". "RVO" означает "оптимизацию возвращаемого значения", и это оптимизация компилятора, которая препятствует вызову любого конструктора перемещения или копирования. Например.

std::vector<huge_thing> foo()
{
    std::vector<huge_thing> result{/* ... */};
    return result;
}

void bar()
{
    auto v = foo(); // (0)
}

Любой достойный компилятор не выполнит никакой операции копирования/перемещения и просто построит v на месте в (0). В С++ 17 это обязательный, благодаря изменениям в prvalues.


С точки зрения дорогостоящих движений: конечно, могут быть дороги, которые нужно переместить - но я не могу придумать ни одного экземпляра, в котором движение было бы дороже, чем копия.

Таким образом:

  • Полагайтесь на RVO, особенно на С++ 17 - это не требует никаких затрат даже для типов, "дорогостоящих для перемещения".

  • Если тип дорогой для перемещения, он также очень дорог для копирования - так что у вас на самом деле нет выбора. Перепроектируйте свой код так, чтобы вам не понадобилось копировать/перемещать, если это возможно.