std::move для объекта, возвращенного функцией

99
03 сентября 2019, 03:00

Имеется один файл main.cpp, в котором определены две глобальные функции getSomeResultFromSomeFunc(), processResult() и функция main():

std::string getSomeResultFromSomeFunc() {
    std::string result;
    if ( cond1 ) {
        // result = ...
    } else if ( cond2 ) {
        // result = ...
    }
    return result;
}
void processResult( const std::string& result ) {
    ...
}
int main(void) {
    std::string myResult = std::move( getSomeResultFromSomeFunc() );
    processResult( myResult );
    return 0;
}

Надо ли использовать std::move() при создании объекта myResult из другого объекта, который возвращается функцией? Чтобы вызывался конструктор перемещения для объекта myResult вместо конструктора копирования, так как это более быстрый способ создания объекта? Или компилятор автоматически вызовет конструктор перемещения вместо конструктора копирования, и использование std::move избыточно? И поэтому достаточно написать проще?

std::string myResult = getSomeResultFromSomeFunc();

или

std::string myResult( getSomeResultFromSomeFunc() );

Для user-defined типов легко проверить как ведет себя компилятор, а для типов из std никак не проверить?

Есть ли различия в использовании std::move для C++0x и C++11 в этом случае ?

Answer 1

Результат, возвращенный функцией в вашем примере, является prvalue. Никакого смысла применять к нему std::move нет.

Своим std::move вы скорее заставите компилятор выполнить temporary materialization conversion там, где в ней никакой необходимости не было, а также подавите оптимизации (return value optimizations - RVO), искусственно "оторвав" инициализируемый объект myResult от его инициализатора result.

В самом лучшем случае успешного RVO в вашем коде не будет ни перемещения ни копирования - результат функции будет конструироваться прямо в вашем myResult.

Обратите внимание: https://godbolt.org/z/_4tnNh
Функция getSomeResultFromSomeFunc сразу получает на вход адрес получателя (myResult) в регистре rdi и всю дальнейшую работу ведет напрямую именно с myResult. Никакого локального result не создается вообще и никакого копирования/перемещения результата не выполняется.

READ ALSO
Доступ к файлу proc//mem

Доступ к файлу proc//mem

При прохождении одного из онлайн тестов наткнулся на сложный вопросВопрос формулируется примерно так:

119
Как спарсить строку?

Как спарсить строку?

Есть строка вида: "40 1234567 12"

139
Передать сигнал и слот QT как параметр

Передать сигнал и слот QT как параметр

Есть библиотека которая общается с устройством либо через usb, либо через ethernet, либо еще через что тоИ хотелось бы что бы передать в конструктор...

99