تعديل محتويات ناقلات في BOOST_FOREACH
سؤال
وهذا هو السؤال الذي يذهب إلى مدى BOOST_FOREACH يتحقق انها إنهاء حلقة
cout << "Testing BOOST_FOREACH" << endl;
vector<int> numbers; numbers.reserve(8);
numbers.push_back(1); numbers.push_back(2); numbers.push_back(3);
cout << "capacity = " << numbers.capacity() << endl;
BOOST_FOREACH(int elem, numbers)
{
cout << elem << endl;
if (elem == 2) numbers.push_back(4);
}
cout << "capacity = " << numbers.capacity() << endl;
ويعطي الانتاج
Testing BOOST_FOREACH
capacity = 8
1
2
3
capacity = 8
ولكن ماذا عن عدد (4) التي تم إدراجها منتصف الطريق خلال الحلقة؟ إذا قمت بتغيير نوع إلى قائمة سيتم كرر عدد إدراجها حديثا قد انتهت. فإن عملية مكافحة ناقلات push_back يبطل أي مؤشرات إذا كنت بحاجة لإعادة تخصيص، ولكن هذا لا يحدث في هذا المثال. لذا فإن السؤال اعتقد هو لماذا يفعل مكرر نهاية () تظهر فقط ليتم تقييمها مرة واحدة (قبل حلقة) عند استخدام ناقلات ولكن لديه تقييم أكثر ديناميكية عند استخدام قائمة؟
المحلول
وتحت الأغطية، والاستخدامات BOOST_FOREACH التكرارات لاجتياز العنصر سلسلة من الأشياء ذات الصلة التي تظهر في ترتيب معين. قبل تنفيذ حلقة، تم تخزينها مؤقتا مكرر غاية في محلية متغير. وهذا ما يسمى الرفع، و ذلك هو الأمثل المهم. هذا يفترض، مع ذلك، أن نهاية مكرر من تسلسل مستقر. هذا وعادة ما يكون، ولكن إذا أردنا تعديل تسلسل عن طريق إضافة أو إزالة عناصر بينما نحن بالتكرار عبر ذلك، فإننا قد ينتهي رفع أنفسنا على المتفجر الخاصة بنا.
اقتباس فقرة>http://www.boost.org/ وثيقة / يبس / 1_40_0 / وثيقة / أتش تي أم أل / foreach / pitfalls.html
إذا كنت لا تريد مكرر نهاية () لتغيير استخدام تغيير حجم على ناقلات بدلا من الاحتياطي.
http://www.cplusplus.com/reference/stl/vector/resize /
لاحظ أن بعد ذلك كنت لا تريد أن push_back لكن استخدام عامل التشغيل [] بدلا من ذلك. ولكن كن حذرا من الذهاب خارج الحدود.
نصائح أخرى
ووأثيرت مسألة في التعليقات لماذا التصحيح وقت التشغيل مايكروسوفت يثير هذا التأكيد خلال التكرار على ناقلات ولكن ليس على القائمة. والسبب هو أن يعرف insert
بشكل مختلف عن list
وvector
(لاحظ أن push_back
هو مجرد insert
في نهاية التسلسل).
ولكل معيار C ++ (ISO / IEC 14882: 2003 23.2.4.3، <م> ناقلات معدلات م>):
<اقتباس فقرة>[على الإدراج]، إذا حدث أي إعادة تخصيص، تظل جميع المكررات والمراجع قبل نقطة الإدراج سارية المفعول.
اقتباس فقرة>و(23.2.2.3، <م> قائمة معدلات م>):
<اقتباس فقرة>[إدراج] لا يؤثر على صحة المكررات والمراجع.
اقتباس فقرة> وهكذا، إذا كنت تستخدم push_back
(ونحن على يقين من أنه لن يؤدي إلى إعادة توزيع)، أنها بخير مع أي حاوية الاستمرار في استخدام مكرر لتكرار على بقية التسلسل.
في حالة ناقلات، ومع ذلك، فإنه على سلوك غير معرف لاستخدام مكرر end
الذي حصلت عليه قبل push_back
.
هذا هو الجواب دوار لهذه المسألة؛ انها الإجابة المباشرة للمناقشة في تصريحات السؤال ل. م>
وforeach دفعة وستنتهي عندما يكون مكرر == numbers.end ()
كن حذرا رغم ذلك، داعيا push_back يمكن / سوف يبطل أي المكررات الحالية لديك.