Відповіді:
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, щоб пропустити виконання ходу або скопіювати взагалі. Я рекомендую вам прочитати посилання 101 BoostCon09 Rvalue, де пояснюється це питання, і як (N) RVO трапляється взаємодіяти з цим.
Ваш випадок повернення рецензії на оцінку було б гарною ідеєю в інших випадках. Уявіть, у вас є getAB()
функція, яку ви часто використовуєте тимчасово. Це не оптимально, щоб він повертав посилання const lvalue для тимчасових тем rvalue. Ви можете реалізувати це так
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Зауважте, що move
в цьому випадку це необов’язково, оскільки ab
це не є ні локальним автоматичним, ні тимчасовим рейтингом. Тепер, ref- &&
kvalifier каже, що друга функція викликається у часових значень 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()
просто використовується як явний акторський склад, щоб більш чітко проілюструвати точку. Це не код, який ви б скопіювали та вставили у свій проект. Це не суперечить голосовій відповіді, оскільки там всередині функції створюється тимчасовий об'єкт. Тут повернутий об’єкт є одним із аргументів (тимчасові об’єкти знищуються як останній крок в оцінці повного виразу, який (лексично) містить точку, де вони були створені).