حاوية C ++ "انتقال من"
-
22-09-2019 - |
سؤال
في 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;
};