سؤال

علي سبيل المثال:

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}
هل كانت مفيدة؟

المحلول

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 المراجع 101 الذي يفسر الأمر، وكيف يحدث (ن) RVO التفاعل مع هذا.


ستكون قضيتك من إرجاع مرجع RVALUE فكرة جيدة في مناسبات أخرى. تخيل أن لديك getAB() وظيفة التي تدلت غالبا في مؤقت. انها ليست الأمثل لجعلها إرجاع مرجع مضغوط lvalue الخاص بتأيارات rvalue. يمكنك تنفيذ ذلك مثل هذا

struct Beta {
  Beta_ab ab;
  Beta_ab const& getAB() const& { return ab; }
  Beta_ab && getAB() && { return move(ab); }
};

لاحظ أن move في هذه الحالة ليست اختيارية، ل ab ليس التلقائي المحلي ولا rvalue مؤقت. الآن، المرجع التصفيات && يقول أن الوظيفة الثانية تم استدعاءها على مؤقتات 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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top