std::transform
التحويل بين النطاقات std::transform
std::transform تطبّق دالة على كل عنصر بنطاق مصدر وتضع النتيجة بنطاق وجهة — يبني نطاقًا جديدًا من نطاق موجود بدل تعديله مباشرة.
على عكس for_each التي غالبًا تعدّل العناصر الأصلية بمكانها، الاستخدام النموذجي لـ transform هو بناء حاوية نتيجة جديدة من حاوية مصدر: كل عنصر بالمصدر يُمرَّر لدالة، والناتج يُكتب بموضع مطابق بحاوية الوجهة (التي يجب أن تكون بحجم كافٍ مسبقًا، أو تُستخدم مع back_inserter لتنمو تلقائيًا).
الصياغة
std::transform(sourceBegin, sourceEnd, destBegin, function);
📄 مثال
#include <algorithm>
#include <vector>
std::vector<int> nums = {1, 2, 3, 4};
std::vector<int> squared(nums.size()); // حجم مسبق كافٍ
std::transform(nums.begin(), nums.end(), squared.begin(),
[](int n) { return n * n; });
// squared: 1 4 9 16 — nums لم يتغيّر إطلاقًاأهم النقاط
| العنصر | الوظيفة |
|---|---|
| sourceBegin, sourceEnd | نطاق العناصر المصدر التي ستُطبَّق عليها الدالة |
| destBegin | بداية نطاق الوجهة — يجب أن يتّسع للنتائج (أو استخدم back_inserter) |
| std::back_inserter(container) | يجعل الوجهة تنمو تلقائيًا بدل الاعتماد على حجم مسبق محدد |
💡 نصائح عملية
- استخدم std::back_inserter(dest) كوجهة عندما لا تعرف الحجم النهائي مسبقًا، بدل حجز حجم يدوي قد يكون خاطئًا
- transform لا تعدّل الحاوية المصدر إطلاقًا افتراضيًا — للتعديل بمكانه، مرّر نفس الحاوية كمصدر ووجهة معًا
⚠️ أخطاء شائعة
- تمرير حاوية وجهة فارغة (بلا حجز حجم أو back_inserter) — سلوك غير معرَّف لأن transform تكتب مباشرة على مواضع موجودة
- توقّع أن transform تعدّل حاوية المصدر تلقائيًا — بخلاف for_each، الفكرة الأساسية هي إنتاج نتيجة بحاوية منفصلة
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار CPP الكامل بالعربي.