سؤال

في C ++ 11 ، يمكننا الحصول على دفعة الكفاءة باستخدام std::move عندما نريد نقل القيم (النسخ المدمرة) إلى حاوية:

SomeExpensiveType x = /* ... */;
vec.push_back(std::move(x));

لكن لا يمكنني العثور على أي شيء يسير في الاتجاه الآخر. ما أعنيه هو شيء من هذا القبيل:

SomeExpensiveType x = vec.back(); // copy!
vec.pop_back(); // argh

هذا أكثر تواترا (نسخ البوب) على محول مثل stack. يمكن أن يكون هناك شيء من هذا القبيل:

SomeExpensiveType x = vec.move_back(); // move and pop

لتجنب نسخة؟ وهل هذا موجود بالفعل؟ لم أتمكن من العثور على أي شيء من هذا القبيل في N3000.

لدي شعور بأنني أفتقد شيئًا واضحًا بشكل مؤلم (مثل عدم الحاجة إليه) ، لذلك أنا مستعد لـ "Ru dum". : 3

هل كانت مفيدة؟

المحلول

قد أكون مخطئًا تمامًا هنا ، لكن ليس ما تريده فقط

SomeExpensiveType x = std::move( vec.back() ); vec.pop_back();

على افتراض أن SomeExpensivetype لديه مُنشئ نقل. (ومن الواضح أنه صحيح بالنسبة لحالتك)

نصائح أخرى

من أجل الاكتمال (وأي شخص يتعثر في هذا السؤال بدون برنامج التحويل البرمجي C ++ 1x) ، وهو بديل موجود بالفعل اليوم:

SomeExpensiveType x;
std::swap(x, vec.back()); 
vec.pop_back();

يتطلب فقط تخصص std::swap لوجود لنوع العنصر.

template<class C>
auto pop_back(C& c) -> typename std::decay<decltype(c.back())>::type
{
  auto value (std::move(c.back()));
  c.pop_back();
  return value;  // also uses move semantics, implicitly
  // RVO still applies to reduce the two moves to one
}

بشكل عام ، أعتقد أنك تريد دفع فئة غلاف أو مؤشر ذكي في الحاوية بدلاً من ذلك. وبهذه الطريقة ، تتجنب نسخًا باهظة الثمن ، وبدلاً من ذلك ، تقوم فقط بالنسخ الرخيصة من المؤشر الذكي أو فئة Wrapper. يمكنك أيضًا استخدام المؤشرات الأولية أيضًا إذا كنت تريد هاها.

class ExpensiveWrapper
{
public:
   ExpensiveWrapper(ExpensiveClass* in) { mPtr = in; }

   // copy constructors here....

private:
   ExpensiveWrapper* mPtr;

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