أقرت لجنة توحيد معايير لغة C++ التابعة للمنظمة الدولية للمعايير (ISO) النسخة النهائية من المواصفات التي تُشكل المعيار الدولي "C++26". وتُدعم الميزات الواردة في هذه المواصفات جزئيًا في مُجمّعات GCC وClang وMicrosoft Visual C++. كما تم دمج المكتبات القياسية الداعمة لـ C++26 ضمن مشروع Boost.
خلال الشهرين المقبلين، ستخضع المواصفة المعتمدة لمرحلة إعداد الوثائق، حيث ستُجرى خلالها عمليات تصحيح تحريرية لمعالجة الأخطاء الإملائية والمطبعية. وفي أوائل نوفمبر، سيتم تقديم النسخة النهائية من الوثيقة إلى المنظمة الدولية للمعايير (ISO) لنشرها تحت الاسم الرسمي ISO/IEC 14882:2026.
الميزات الرئيسية لـ C++26:
- تم تطبيق عناصر برمجة العقود (العقود)، مما يسمح لك بتحديد مواصفات واجهة رسمية باستخدام ثلاثة عوامل تشغيل جديدة: pre (الشرط المسبق)، وpost (الشرط اللاحق)، وcontract_assert (التحقق من التأكيد). يُحدد عامل التشغيل "pre" الشروط المسبقة التي يجب استيفاؤها قبل الاستدعاء (التحقق من صحة المدخلات)؛ ويُحدد عامل التشغيل "post" الشروط التي يجب استيفاؤها بعد التنفيذ (متطلبات المخرجات)؛ بينما يُحدد عامل التشغيل contract_assert شروط إطلاق الاستثناءات. ستكون هذه الميزة متاحة في GCC 16. int f(const int x) pre (x != 1) // متطلبات المدخلات post (r : r == x && r != 2) // متطلبات النتيجة؛ r هي القيمة التي تُمثل النتيجة { contract_assert (x != 3); return x; }
- تمت إضافة دعم الانعكاس، مما يسمح بمراقبة عناصر البرنامج وتعديلها أثناء الترجمة. كما تمت إضافة عاملين جديدين: "^^" للحصول على معلومات وصفية حول بنية القواعد، و"[:…:]" لإجراء التحويل العكسي. يُقترح استخدام مكتبة std::meta لتحويل ومعالجة المعلومات التي تم الحصول عليها أثناء الفحص، وتتوفر إمكانيات مثل إجراء العمليات الحسابية على الثوابت. سيتم إضافة دعم الانعكاس في GCC 16. constexpr int i = 42, j = 42; constexpr std::meta::info r = ^^i, s = ^^i; static_assert(r == r && r == s); static_assert(^^i != ^^j); // 'i' و'j' لهما قيم مختلفة. static_assert(constant_of(^^i) == constant_of(^^j)); // 'i' و 'j' متطابقان static_assert(^^i != std::meta::reflect_constant(42)); // يختلف عن القيمة 42
- أُضيفت خاصية "template for" للتكرار على عناصر مثل حزم المعاملات، والكائنات الشبيهة بالصفوف، ونتائج الانعكاس (الكائنات الوصفية) أثناء وقت الترجمة، على غرار حلقة for العادية. عند تنفيذ "template for"، يتم توسيع جسم الحلقة لكل عنصر، وتُعالج كل تكرارة في نطاق منفصل يكون فيه المتغير المتغير في الحلقة ثابتًا. في سياق الانعكاس، يمكن استخدام "template for" للتكرار على خصائص الفئات أو التعدادات. ستتوفر هذه الميزة في GCC 16. سيتم توسيع الكود التالي: `void f() { template for (constexpr int I : std::array{1, 2, 3}) { static_assert(I < 4); } }` إلى: `void f() { { constexpr auto&& __range = std::array{1, 2, 3}; constexpr auto __begin = __range.begin(); } }` constexpr auto __expansion-size = __range.end() — __begin; // 3 { constexpr int I = *(__begin + 0); static_assert(I < 4); } { constexpr int I = *(__begin + 1); static_assert(I < 4); } { constexpr int I = *(__begin + 2); static_assert(I < 4); } } }
- تمت إضافة إطار عمل std::execution لتنفيذ التعليمات البرمجية غير المتزامنة والمتوازية. يوفر هذا الإطار كائنات جدولة تُحدد مُجدول العمل (الخيط، مجموعة الخيوط، وحدة معالجة الرسومات، حلقة الأحداث)، وكائنات إرسال تُحدد العمل المراد تنفيذه، وكائنات استقبال تُعالج النتيجة. باستخدام مساحة الاسم std::execution؛ scheduler auto sch = thread_pool.scheduler(); sender auto begin = schedule(sch); sender auto hi = then(begin, []{ std::cout < "Hello world! Have an int."; return 13; }); sender auto add_42 = then(hi, [](int arg) { return arg + 42; }); auto [i] = this_thread::sync_wait(add_42).value();
- تمت إضافة مكتبة std::simd لتنفيذ عمليات البيانات بالتوازي باستخدام مجموعات تعليمات SIMD مثل AVX-512 وNEON باستخدام نظام أنواع C++ القياسي. std::simd a = {1.0f, 2.0f, 3.0f, 4.0f}; std::simd b = {5.0f, 6.0f, 7.0f, 8.0f}; std::simd result = a + b;
- يُقترح تطبيقٌ لمتجه (مصفوفة) ذي حجم متغير std::inplace_vector. يُخصَّص هذا المتجه في الذاكرة المكدسة، ويُحدَّد حجمه أثناء الترجمة. واجهة برمجة التطبيقات (API) مشابهة لـ std::vector، ولكن عناصر المصفوفة تُخزَّن داخليًا، وليس في الذاكرة الديناميكية (heap). مثال: `inplace_vector a(10); inplace_vector b(std::move(a)); assert(a.size() == 10);`
- تمت إضافة التوجيه "#embed" لتضمين الموارد الثنائية في الكود. const unsigned char icon_display_data[] = { #embed "art.png" };
- تمت إضافة دعم لإنشاء ومعالجة الاستثناءات في وقت الترجمة عند حدوث أخطاء في سياق constexpr. constexpr std::optional checked_divide(unsigned n, unsigned d) { try { return divide(n, d); } catch (...) { return std::nullopt; } } constexpr date parse_date(std::string_view input) { auto [correct, year, month, day] = ctre::match<“([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})”>(input); if (!correct) { throw incorrect_date{input}; } return build_date(year, month, day); }
- تم تصميم بنية البيانات std::hive لتخزين البيانات غير المرتبة وإعادة استخدام الذاكرة التي تم تحريرها بحذف العناصر. هذه البنية مُحسَّنة لأحمال العمل التي تتضمن إضافة وحذف عناصر بكثافة عالية وبترتيب عشوائي. على عكس المصفوفات، لا يؤدي حذف عنصر في std::hive إلى إزاحة العناصر الأخرى، بل يُعلِّم العنصر المحذوف بأنه فارغ، ثم يملأ الموضع الفارغ عند إضافة عنصر جديد.
- تمت إضافة مكتبة std::linalg مع واجهة برمجة تطبيقات تعتمد على BLAS للجبر الخطي.
- تمت إضافة دعم لآلية مزامنة مؤشر الخطر، التي تمنع تحرير الذاكرة للكائنات التي تصل إليها سلاسل العمليات الأخرى دون تأمينها. عند حذف كائن، يتم فقط وضع علامة عليه كمحذوف، ولكن لا يتم تحرير الذاكرة التي كان يشغلها إلا بعد أن تحرر جميع سلاسل العمليات مؤشر الخطر الذي تم تعيينه أثناء الوصول إلى الكائن.
- تمت إضافة دعم لآلية التزامن RCU (القراءة والنسخ والتحديث). تُنشئ عمليات الكتابة نسخة جديدة من الكائن، بينما لا تُعيق عمليات القراءة عمل البرنامج، بل تستمر في العمل مع النسخة القديمة. بعد اكتمال التغيير، تُصبح النسخة الجديدة نشطة، وتُجرى عليها عمليات قراءة جديدة، بينما تُحذف النسخة القديمة بعد انتهاء جميع عمليات القراءة من قِبل سلاسل العمليات.
- أُجريت تعديلات لتعزيز أمان المكتبة القياسية، مثل التحقق من صحة القيم ومنع تجاوزات المخزن المؤقت. على سبيل المثال، عند الوصول إلى العنصر "constexpr reference operator[](size_type idx) const;"، تمت إضافة فحص للشرط "idx < size()".
- يتم توفير القدرة على استخدام الكلمة المفتاحية constexpr مع أحد متغيرات عامل التشغيل الجديد (placement new) لوضع كائن في الذاكرة المخصصة مسبقًا في وقت الترجمة.
- تمت إضافة دعم للربط المهيكل في سياق "constexpr"، مما يعني أن المراجع إلى التعبيرات الثابتة يمكن أن تكون تعبيرات ثابتة بحد ذاتها. يدعم هذا الإصدار المصفوفات والهياكل البسيطة. مثال: `constexpr int arr[] = {1, 2}; constexpr auto [x, y] = arr;`
- تدعم الارتباطات المنظمة الآن صيغة "..." لتحديد الحزم التي تلتقط العدد المتبقي من العناصر في تسلسل التعيين. auto [x,y,z] = f(); // ستحتوي المتغيرات x و y و z على العناصر الثلاثة التي تم إرجاعها بواسطة f(). auto [...xs] = f(); // ستحتوي الحزمة xs على جميع العناصر التي تم إرجاعها بواسطة f(). auto [x, ...rest] = f(); // سيحتوي x على العنصر الأول، وسيحتوي rest على الباقي. auto [x, y, ...rest] = f(); // سيحتوي x على العنصر الأول، وسيحتوي rest على العنصر الثاني، وسيحتوي rest على العنصر الثالث. auto [x, ...rest, z] = f(); // سيحتوي x على العنصر الأول، وسيحتوي rest على العنصر الثاني، وسيحتوي z على العنصر الثالث.
- أُضيف دعمٌ لخاصية "النقل السهل" للأنواع، والتي تُتيح تحسين حركة كائنات نوعٍ مُعين باستنساخها في الذاكرة دون الحاجة إلى استدعاء مُنشئات أو مُدمرات. تم تطبيق الخاصيتين memberwise_trivially_relocatable وmemberwise_replaceable للفئات، وأُضيفت الدالتان trivially_relocate_at وtrivially_relocate للنقل البسيط لكائن واحد أو أكثر.
- تم تطبيق دعم لربط الدالة main() بوحدة نمطية عامة وتحديد الدالة main() في الوحدات النمطية المسماة.
- تمت إضافة عامل التشغيل المتغير "صديق" ("صديق Ts...").
- تم تطبيق السمات الخاصة بالروابط المهيكلة؛
- تمت إضافة الصيغة '= delete("reason")'.
- تتضمن مجموعة الأحرف الأساسية "@" و "$" و "`".
- تتوفر إمكانية استخدام الربط المنظم كشرط في عبارات if و switch.
- تمت إضافة القدرة على استخدام متغيرات نائبة متعددة تسمى "_" في نطاق واحد، على سبيل المثال، أصبحت البنيات التالية صحيحة الآن: struct S { int _, _; }; دالة void() { int _, _; } void other() { int _; // في السابق كان يتم عرض تحذير في وضع -Wunused }
- توفر القدرة على استخدام الأحرف النصية في سياق لا يتم استخدامها لتهيئة مصفوفة أحرف ولا تظهر في الكود الناتج، ولكن يتم استخدامها فقط أثناء التجميع للرسائل التشخيصية والمعالجة المسبقة، مثل المعلمات لتوجيهات وسمات _Pragma وasm وextern وstatic_assert و[[deprecated]] و[[nodiscard]].
- تمت إضافة وظائف مدمجة: "__builtin_is_within_lifetime" للتحقق مما إذا كان البديل نشطًا في الاتحادات و "__builtin_is_virtual_base_of" للتحقق مما إذا كانت الفئة الأساسية افتراضية.
- تم تنفيذ حلقات تكرار لا نهائية بسيطة بدون سلوك غير محدد.
- تم التأكد من عرض خطأ عند حذف مؤشر إلى نوع غير مكتمل.
- لقد تم إيقاف استخدام بناء الجملة لتحديد المعلمات المتغيرة باستخدام علامة حذف بدون فاصلة سابقة (على سبيل المثال، عند تحديد "void e(int…)" بدلاً من "void e(int, …)").
- يُحظر استخدام وحدات الماكرو للإعلان عن الوحدات النمطية.
- تم إيقاف استخدام التحويلات الضمنية للقيم المُعدّدة في العمليات الحسابية. int main() { enum E1 { e }; enum E2 { f }; bool b = e <= 3.7; // مُهمل int k = f - e; // مُهمل int x = +f - e; // صحيح }
- تم إيقاف دعم المقارنة المباشرة للمصفوفات. int arr1[5]; int arr2[5]; bool same = arr1 == arr2;
- لقد تم إيقاف استخدام فئة القالب is_trivial.
المصدر: opennet.ru
