لماذا لا يستدعي رمز C ++ 0x هذا مُنشئ Move؟
سؤال
لسبب ما ، لا يستدعي الرمز التالي أبدًا Event::Event(Event&& e)
Event a;
Event b;
Event temp;
temp = move(a);
a = move(b);
b = move(temp);
لما لا؟
استخدام std::swap
يسميها مرة واحدة.
class Event {
public:
Event(): myTime(0.0), myNode(NULL) {}
Event(fpreal t, Node* n);
Event(Event&& other);
Event(Event const& other) = delete;
~Event();
bool operator<(Event const& other) const { return myTime < other.myTime; }
bool operator>(Event const& other) const { return myTime > other.myTime; }
fpreal getTime() const { return myTime; }
void setTime(fpreal time) { myTime = time; }
Node* getNode() const { return myNode; }
private:
fpreal myTime;
Node* myNode;
};
المحلول
يحتوي الكود الخاص بك على موقعين محتملين للمكان الذي قد يتوقع فيه المرء أن يتم استدعاء مُنشئ الحركة (ولكنه لا):
1) استدعاء الأمراض المنقولة جنسيا :: تحرك
2) أثناء المهمة.
بخصوص 1) ، يقوم STD :: Move بإجراء طاقم بسيط - لا ينشئ كائنًا من نسخة - إذا حدث ذلك ، فقد يتم الاحتجاج بمنشئ الحركة ، ولكن نظرًا لأنه يقوم بمجموع RVALUE بسيط ، فلن يتم الاحتجاج به . تعريف STD :: MOVE مشابه لـ static_cast<Event&&>(temp)
.
فيما يتعلق 2) ، فإن التهيئة والتعيين هي عمليتان مختلفتان تمامًا (على الرغم من أن بعض أشكال التهيئة تستخدم رمز "= '). يقوم الرمز الخاص بك بالتعيين وبالتالي يستخدم مشغل الواجب الافتراضي الذي يُعلن أنه يقبل مرجع const lvalue. نظرًا لأنك لا تقوم بتهيئة كائن حدث واحد أبدًا ، فلن ترى مُنشئًا نقلك يتم استدعاءه. إذا أعلنت عن مشغل مهمة نقل: Event& operator=(Event&& other)
, ، فإن الكود الحالي الخاص بك سوف يستدعيه أو إذا كتبت: Event a; Event tmp = move(a);
مُنشئك ، كما هو مكتوب ، سيتم الاحتجاج به.
نصائح أخرى
أنت لا تستخدم مُنشئ الحركة. أعتقد أن المبادلة تنفذ شيئًا كهذا
Event a;
Event b;
Event temp(move(a)); // this one wants to use a move constructor
a = move(b);
b = move(temp);
تريد استخدام مشغل تعيين Move ، والذي لا يوجد في الكود الخاص بك ، لذلك يعود إلى مشغل تعيين النسخ.