C++17: ما الجديد؟ دليل كامل مع أمثلة للمحترفين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

ماذا قدم C++17؟ تحليل أبرز مستجدات المعيار

\n\n

إذا كنت تكتب بلغة C++ وتريد البقاء في التيار الرئيسي، فإن C++17 هو الإصدار الذي يجب أن تتقنه الآن. تم إصداره في عام 2017، ولكن لا تزال العديد من المشاريع "عالقة" على C++14 أو حتى C++11، خوفًا من الانتقال إلى المعيار الجديد. وهذا خطأ.

\n\n

في هذه المقالة، سنقوم بتحليل ميزات C++17 الجديدة من خلال أمثلة واقعية. ستتعلم كيفية تبسيط الكود، والتخلص من الفحوصات غير الضرورية، وجعل البرامج أسرع. لن نقوم بإدراج جميع التغييرات البالغ عددها 105 - فقط ما سيفيدك حقًا في العمل.

\n\n

1. الروابط الهيكلية (Structured Bindings) - التفكيك في ثانية

\n\n

واحدة من أكثر ميزات C++17 ملاءمة هي الروابط الهيكلية. في السابق، لتفكيك tuple أو pair، كان عليك كتابة std::tie أو الوصول عبر الفهارس. الآن أصبح الأمر أكثر أناقة.

\n\n

مثال: إرجاع قيم متعددة من دالة

\n\n
#include <iostream>\n#include <tuple>\n#include <string>\n\nstd::tuple<int, std::string, double> getData() {\n    return {42, "الإجابة", 3.14};\n}\n\nint main() {\n    // C++17: سطر واحد بدلاً من std::tie\n    auto [id, name, value] = getData();\n    std::cout << name << ": " << id << " (" << value << ")\\n";\n    return 0;\n}
\n\n

ما الذي تغير؟ في السابق، كان عليك تعريف المتغيرات بشكل منفصل ثم استدعاء std::tie. الآن auto [a, b, c] يقوم بكل العمل نيابة عنك.

\n\n

الروابط الهيكلية لا تعمل فقط مع tuples، بل أيضًا مع المصفوفات وأي هياكل تحتوي على حقول عامة. هذا أحد ابتكارات C++17 التي تجعل الكود أنظف وأكثر قابلية للقراءة.

\n\n

2. std::optional - التخلص من القيم "السحرية"

\n\n

كم مرة رأيت كودًا حيث ترجع الدالة -1 أو nullptr للإشارة إلى خطأ؟ أو الأسوأ من ذلك - علامة bool والنتيجة عبر مرجع؟ std::optional<T> يحل هذه المشكلة مرة واحدة وإلى الأبد.

\n\n

مثال: بحث آمن في حاوية

\n\n
#include <iostream>\n#include <optional>\n#include <map>\n#include <string>\n\nstd::optional<int> findValue(const std::map<std::string, int>& m, const std::string& key) {\n    auto it = m.find(key);\n    if (it != m.end()) {\n        return it->second;  // توجد قيمة\n    }\n    return std::nullopt;    // لا توجد قيمة\n}\n\nint main() {\n    std::map<std::string, int> ages = {{"Alice", 30}, {"Bob", 25}};\n    \n    auto result = findValue(ages, "Charlie");\n    if (result) {\n        std::cout << "تم العثور: " << *result << "\\n";\n    } else {\n        std::cout << "لم يتم العثور على المفتاح\\n";\n    }\n    \n    // أو استخدم value_or للحصول على قيمة افتراضية\n    int age = result.value_or(0);\n    return 0;\n}
\n\n

std::optional هو حاوية يمكن أن تحتوي على قيمة أو تكون فارغة. تتحقق منها عبر if (opt)، وتحصل على القيمة عبر *opt أو opt.value(). هذا أكثر أمانًا بكثير من أكواد الأخطاء "الاتفاقية".

\n\n

3. if constexpr - قوالب بدون صداع

\n\n

ميزات C++17 الجديدة للبرمجة الفوقية هي مجرد هدية. if constexpr يسمح بتنفيذ التجميع الشرطي داخل القوالب دون بهلوانيات SFINAE.

\n\n

مثال: دالة عالمية لأنواع مختلفة

\n\n
#include <iostream>\n#include <type_traits>\n#include <string>\n\ntemplate <typename T>\nvoid printInfo(const T& value) {\n    if constexpr (std::is_integral_v<T>) {\n        std::cout << "عدد صحيح: " << value << "\\n";\n    } else if constexpr (std::is_floating_point_v<T>) {\n        std::cout << "عدد عائم:                

المدونات

توصيات الكتب