Ответы:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Это возвращает висящую ссылку, как и в случае ссылки lvalue. После возврата из функции временный объект будет уничтожен. Вы должны вернуться Beta_ab
по значению, как показано ниже
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
Теперь он правильно перемещает временный Beta_ab
объект в возвращаемое значение функции. Если компилятор может, он вообще избежит перемещения, используя RVO (оптимизация возвращаемого значения). Теперь вы можете сделать следующее
Beta_ab ab = others.toAB();
И он переместит конструкцию временного в ab
или сделает RVO, чтобы вообще не выполнять перемещение или копирование. Я рекомендую вам прочитать BoostCon09 Rvalue References 101, в котором объясняется этот вопрос и как (N) RVO взаимодействует с этим.
Ваш случай возврата ссылки rvalue был бы хорошей идеей в других случаях. Представьте, что у вас есть getAB()
функция, которую вы часто вызываете временно. Не оптимально заставлять его возвращать ссылку на const lvalue для временных rvalue. Вы можете реализовать это так
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Обратите внимание, что move
в этом случае это не является обязательным, поскольку не ab
является ни локальным автоматическим, ни временным rvalue. Теперь квалификатор ref &&
говорит, что вторая функция вызывается во временных файлах rvalue, делая следующий ход вместо копирования
Beta_ab ab = Beta().getAB();
Это может быть более эффективно, например, в немного другом контексте:
template <typename T>
T&& min_(T&& a, T &&b) {
return std::move(a < b? a: b);
}
int main() {
const std::string s = min_(std::string("A"), std::string("B"));
fprintf(stderr, "min: %s\n", s.c_str());
return 0;
}
Интересно отметить, что на моем компьютере clang++ -O3
генерируется 54 инструкции для приведенного выше кода по сравнению с 62 инструкциями для обычного std::min
. Однако с -O0
его помощью генерируется 518 инструкций для кода выше по сравнению с 481 для обычного std::min
.
for(:)
и интегрировали освобожденный объект. Исправление: ideone.com/tQVOal
std::move()
используется просто как явное приведение, чтобы более четко проиллюстрировать суть. Это не тот код, который вы бы скопировали и вставили в свой проект. Это не противоречит ответу, получившему наибольшее количество голосов, потому что внутри функции создается временный объект. Здесь возвращаемый объект является одним из аргументов (временные объекты уничтожаются на последнем этапе оценки полного выражения, которое (лексически) содержит точку, в которой они были созданы).