مخصص مخصص باستخدام Move for Vector of Thread
-
25-09-2019 - |
سؤال
أنا أتعلم حاليًا عن التزامن في C ++ وصادف باستخدام متجه من المواضيع ، والتي أعتقد أنها ستكون ممكنة في C ++ 0x. ومع ذلك ، لا يبدو أن برنامج التحويل البرمجي الحالي الخاص بي يحتوي على تنفيذ حاويات على دراية بالتحرك ولذا فإنني أحصل على أخطاء بسبب std::thread::thread(const std::thread&)
تم حذفه ، أي لا يمكنني إلا استخدام مهمة مُنشئ/نقل الحركة مع std::thread
.
هل أنا محق في التفكير في أنه يمكنني التحايل على هذه المشكلة عن طريق كتابة مخصص مخصص باستخدامه
void MyAllocator::construct (pointer p, reference val)
/* should be non-const reference to val because using move constructor? */
{
new ((void*)p) T (std::move(val));
}
عوضا عن
void allocator::construct (pointer p, const_reference val)
{
new ((void*)p) T (val);
}
؟ أو بعض الاختلافات الأخرى في هذا الموضوع (ربما باستخدام حمولة زائدة من MyAllocator :: Construct).
NB: يهدف هذا بشكل أساسي إلى أن يكون تمرينًا تعليميًا قصير الأجل وتجهيزًا ما يكفي من العمل للعب مع خيوط في الحاويات. سأستخدم فقط MyAllocator
في هذا السياق. ومع ذلك ، يرجى أيضًا توجيهني إلى أي مكتبات قد تكون قد تم تنفيذها حتى أتمكن من الحصول على كزة حول المصدر.
المحلول
إذا لم يقدم المترجم الخاص بك مدركًا std::vector
ثم يجب عليك كتابة تخصصك الخاص std::vector<std::thread>
بدلا من مجرد توفير مخصص مخصص. كل C ++ 03 vector
تعتمد الواجهة على النسخ: push_back()
نسخ عناصر في ؛ resize()
تهيئة العناصر الفارغة مع أ ينسخ تم تمرير العنصر كمعلمة ثانية (حتى لو كانت هذه هي القيمة الافتراضية لـ T()
); resize()
, reserve()
, insert()
, erase()
و push_back()
إرادة ينسخ العناصر إذا كان المتجه يحتاج إلى إعادة تخصيص ، أو تحتاج العناصر إلى التنقل ، وما إلى ذلك.
هذه مشكلة شائعة لدرجة أنني قمت بتضمين مثل هذا التخصص مع (التجاري) فقط :: الموضوع بداية شئ std::thread
.
نصائح أخرى
أسهل طريقة للتحايل على المشكلة هي تخصيص الخيوط على الكومة والتلاعب بها.
افحص ال Boost Pointer Container
مكتبة: boost::ptr_vector<std::thread>
يبدو لي ما تبحث عنه.
إن متطلبات أن حاويات STD تأخذ فقط كائنات قابلة للنسخ لا علاقة لها بواجهات حاوية C ++ 03 أكثر من تنفيذ مخصص. علي سبيل المثال
vector<T> b(100);
vector<T> a;
a=b;
assert(a==b);
المعيار يؤكد لنا A == B صحيح. ومع ذلك ، إذا لم تكن T قابلة للنسخ ، فلن يتم ترجمة A في أفضل حالة A = B ، في أسوأ A = B غير محدد. بالإضافة إلى،
a.push_back(T());
قد يتسبب في تخصيص مساحة جديدة ، وتحت غطاء محرك السيارة ، توجد نسخ تم إعدادها إلى التخزين الأساسي الجديد من القديم.
علاوة على ذلك ، لا يوجد شيء في معيار C ++ 03 الذي يقول إن التنفيذ يجب أن يستدعي بالفعل تخصيص.
يضيف المعيار C ++ 0x وظائف عضو جديدة إلى واجهة الحاوية لأنواع متحركة ، ويوضح كيف أن أشياء مثل المشغل = تتصرف في وجودها.
انظر www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2486.pdf