0Pricing
C++ Academy · درس

‏std::move وstd::forward

حوّل lvalues إلى rvalues باستخدام std::move، وحافظ على فئة القيمة باستخدام std::forward.

‏std::move وstd::forward درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

قريبتان بوظيفتين مختلفتين

كل من std::move وstd::forward تحويل نوع في وقت الترجمة. تبدوان متشابهتين، لكنهما تحلان مشكلتين مختلفتين.

‏std::move: تحويل دائم إلى rvalue

يحوّل std::move(x)، دون شروط، x إلى مرجع rvalue. ويمكن للدالة التي تتلقى الكائن بعد ذلك الاستيلاء على موارده.

std::string s = "Hello";
std::string t = std::move(s);   // move-constructs t from s
// s is now in a valid-but-unspecified state

متى تستخدم move؟

استخدم std::move في:

  • مُنشئات النقل وعوامل إسناد النقل
  • إرجاع متغير محلي عندما تريد فرض النقل (وهو أمر نادر الحاجة — فعادةً ما ينطبق RVO)
  • تمرير متغير محلي لم تعد تحتاج إليه إلى دالة تستقبل الكائن للنقل

تنفيذ std::move

إنه في الحقيقة مجرد static_cast متخفٍّ:

template <typename T>
typename std::remove_reference<T>::type&& move(T&& t) noexcept {
    return static_cast<typename std::remove_reference<T>::type&&>(t);
}

‏std::forward: الحفاظ على الفئة

في قالب يستخدم مرجع تمرير (T&&)، يحوّل std::forward<T>(x) ‏x إلى فئته الأصلية (lvalue أو rvalue). ويُستخدم للتمرير المثالي.

template <typename T>
void wrapper(T&& arg) {
    target(std::forward<T>(arg));  // forwards as lvalue or rvalue depending on T
}

لماذا نحتاج إلى التمرير؟

داخل القالب، للوسيط اسم، ما يجعله lvalue حتى إذا مرّر المستدعي rvalue. يستعيد std::forward الفئة الأصلية.

من دون std::forward

من دون forward، سيمرَّر كل وسيط بوصفه lvalue داخل الغلاف، ما يلغي أي دلالات نقل أرادها المستدعي.

template <typename T>
void wrapper(T&& arg) {
    target(arg);    // always lvalue — wrong
}

حدّد دائمًا وسيط القالب لـ forward

يتطلب std::forward<T> وسيط القالب الصريح. ومن دونه سيكون السلوك غير صحيح.

مثال على التمرير المثالي

تحافظ دالة مصنع تمرّر وسائط المُنشئ على التمييز بين rvalue وlvalue لتحقيق الكفاءة.

template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

انقل مرة واحدة

ينبغي نقل كل كائن مرة واحدة كحد أقصى. وبعد النقل، يكون في حالة صالحة لكن غير محددة — وعادةً ما تعيد إسناد قيمة إليه أو تتلفه. وقد يؤدي استخدام كائن نُقلت موارده من دون إعادة إسناد أولًا إلى أخطاء دقيقة.

قواعد عامة

نموذج ذهني سريع:

  • لديك نوع محدد وتريد نقله → std::move
  • لديك وسيط قالب وتريد الحفاظ على فئته → std::forward<T>

تحقّق سريعًا

داخل دالة قالب ذات وسيط T&& arg، كيف تمرّر arg مع الحفاظ على فئة lvalue أو rvalue الخاصة به؟

مراجعة

يحوّل std::move النوع دون شروط إلى rvalue، لذا استخدمه مع الكائنات المحددة التي تريد الاستيلاء على مواردها. ويحافظ std::forward<T> على فئة القيمة داخل القوالب العامة، لذا يُستخدم للتمرير المثالي.

الأسئلة الشائعة

هل درس «‏std::move وstd::forward» مجاني؟

نعم — نص درس «‏std::move وstd::forward» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «‏std::move وstd::forward»؟

حوّل lvalues إلى rvalues باستخدام std::move، وحافظ على فئة القيمة باستخدام std::forward. تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «‏std::move وstd::forward»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. ‏Lvalue مقابل Rvalue: التمييز بينهما
  2. مراجع Rvalue وصياغة &&
  3. ‏std::move وstd::forward
  4. منشئات النقل وإسناد النقل
← العودة إلى C++ Academy