Итак создаём пример
Какой-то, класс — rvo,
Функция которая создаёт вектор объектов этого класса и возвращает его по значению.
Переменная, которая принимает этот вектор. Т.к. вектор возвращается по значению, чтобы избежать создания нового вектора конструктором копирования, применяем приведение std::move к возвращаемому значению функции, приводя его к rvalue и вызову конструктора перемещения.
#include <utility>
#include <iostream>
#include <vector>
class rvo
{
public:
rvo(const std::string &s="Hello"):str(std::move(s)){ };
void sayHello(){ std::cout<< str <<std::endl;
}
private:
std::string str;
};
auto getRvo(){
std::vector<rvo> vec;
for(auto a = 0; a< 10; ++a){
rvo obj;
vec.push_back(obj);
}
return vec;
}
int main(int argc, char const *argv[])
{
auto j = std::move(getRvo());
for (auto &a:j){
a.sayHello();
}
return 0;
}
Компилируемclang++ rvo.cpp -o rvo -std=c++14 -Wpessimizing-move
И получаем предупреждениеrvo.cpp:38:11: warning: moving a temporary object prevents copy elision [-Wpessimizing-move]
auto j = std::move(getRvo());
^
rvo.cpp:38:11: note: remove std::move call here
auto j = std::move(getRvo());
Смотрим стандарт 12.8.31 — вот нужные нам пункты.
— in a return statement in a function with a class return type, when the expression is the name of a
non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-
unqualified type as the function return type, the copy/move operation
can be omitted by constructing
the automatic object directly into the function’s return value
— when a temporary class object that has not been bound to a reference (12.2) would be copied/moved
to a class object with the same cv-unqualified type,
the copy/move operation can be omitted by
constructing the temporary object directly into the target of the omitted copy/move
Т.ч. если типы создаваемой и возвращаяемой переменной совпадают (помним про Almost Always Auto), тогда применение std::move к объекту возвращаемому из функции по значению, для инициализации нового объекта — излишне. Правильная функция main в примере:
int main(int argc, char const *argv[])
{
auto j = getRvo();
for (auto &a:j){
a.sayHello();
}
return 0;
}