C++: ميزات C++17/20 الجديدة

آخر تحديث: 2026-08-26

في الدرس 47، تعلمنا عن برمجة القوالب الفوقية.

الآن، سنتعلم عن ميزات C++17 وC++20 الجديدة.

هذه الميزات الجديدة تجعل C++ أكثر إيجازًا وأمانًا وقوة.


1. ميزات C++17 الجديدة

(1) 1.1 الربط المهيكل

الميزة: فك ملائم من tuple وpair وstruct.

مثال: الربط المهيكل (الصعوبة ⭐)

▶ مثال 2: مثال على الكود (الصعوبة ⭐)

CPP
#include <iostream>
#include <tuple>

int main() {
	std::tuple<int, std::string, double> t = {1, "Hello", 3.14};
	
	// C++17: الربط المهيكل
	auto [id, name, score] = t;
	
	std::cout << "ID: " << id << std::endl;
	std::cout << "Name: " << name << std::endl;
	std::cout << "Score: " << score << std::endl;
	
	return 0;
}
▶ جرّب الكود

الخرج:

TEXT 📖 للعرض فقط
ID: 1
Name: Hello
Score: 3.14

(2) 1.2 if constexpr

الميزة: if وقت التجميع، تجميع كود بشكل انتقائي بناءً على الشروط.

مثال: if constexpr (الصعوبة ⭐⭐)

CPP
#include <iostream>
#include <type_traits>

template<typename T>
auto process(T value) {
	if constexpr (std::is_integral_v<T>) {
		return value * 2; // عدد صحيح: ضاعفه
	} else {
		return value; // غير ذلك: أعد كما هو
	}
}

int main() {
	std::cout << process(10) << std::endl; // 20
	std::cout << process(3.14) << std::endl; // 3.14
	
	return 0;
}

(3) 1.3 تعابير الطي

الميزة: تبسيط القوالب المتغيرة.

مثال: تعبير الطي (الصعوبة ⭐⭐)

CPP
#include <iostream>

template<typename... Args>
void print(Args... args) {
	(std::cout << ... << args) << std::endl; // تعبير طي
}

int main() {
	print(1, 2, 3, 4, 5); // الخرج: 12345
	return 0;
}

(4) 1.4 ميزات C++17 الأخرى

الميزة الوصف
std::optional قيمة قد تكون فارغة
std::variant اتحاد آمن الأنواع
std::any أي نوع
std::string_view عرض سلسلة (نسخ صفرية)
استنتاج معاملات أصناف القوالب لا حاجة لكتابة pair<int, int> بعد الآن


2. ميزات C++20 الجديدة

(1) 2.1 المفاهيم (Concepts)

الميزة: تقييد معاملات القالب لرسائل خطأ أكثر وضوحًا.

مثال: تقييد القوالب بالمفاهيم (الصعوبة ⭐⭐⭐)

CPP
#include <iostream>
#include <concepts>

// تقييد T ليكون نوعًا صحيحًا
template<typename T>
requires std::integral<T>
T doubleValue(T x) {
	return x * 2;
}

int main() {
	std::cout << doubleValue(10) << std::endl; // 20
	// std::cout << doubleValue(3.14) << std::endl; // ❌ خطأ تجميع (واضح)
	
	return 0;
}

(2) 2.2 مكتبة النطاقات

الميزة: طريقة أكثر إيجازًا لاستدعاء خوارزميات STL.

مثال: استخدام النطاقات (الصعوبة ⭐⭐)

TEXT 📖 للعرض فقط
#include <iostream>
#include <ranges>
#include <vector>

int main() {
	std::vector<int> v = {1, 2, 3, 4, 5};
	
	// C++20: نطاقات
	auto result = v | std::views::filter([](int x) { return x % 2 == 0; })
					| std::views::transform([](int x) { return x * 10; });
	
	for (int x : result) {
		std::cout << x << " "; // الخرج: 20 40
	}
	std::cout << std::endl;
	
	return 0;
}

(3) 2.3 الكوروتينات

الميزة: دعم الكوروتينات (دوال يمكن إيقافها/استئنافها).

مثال: كوروتين بسيط (الصعوبة ⭐⭐⭐⭐)

CPP
#include <iostream>
#include <coroutine>

// الكوروتينات في C++20 معقدة؛ يتم حذف التنفيذ المحدد هنا
// المفهوم: الكوروتينات يمكنها إيقاف التنفيذ واستئنافه لاحقًا

int main() {
	// مثال على كوروتين C++20 (مبسط)
	std::cout << "C++20 Coroutines" << std::endl;
	return 0;
}

(4) 2.4 ميزات C++20 الأخرى

الميزة الوصف
الوحدات تحل محل ملفات الرأس، تجميع أسرع
الكوروتينات البرمجة غير المتزامنة
مكتبة التواريخ (امتدادات chrono) معالجة أفضل للتاريخ/الوقت
مكتبة التنسيق (format) تنسيق بأسلوب Python
عامل المركبة الفضائية (<=>) مقارنة ثلاثية


3. اختيار المعيار

(1) 3.1 أي معيار يجب أن تستخدم؟

المعيار التوصية
C++11 الحد الأدنى من المعيار، يجب استخدامه
C++14 تحسينات طفيفة، موصى به
C++17 ميزات عملية كثيرة، موصى به بشدة
C++20 أحدث الميزات، استخدم بحذر (دعم المترجم قد يكون غير مكتمل)


4. تمرين: إعادة هيكلة الكود بـ C++17

▶ مثال 1: تبسيط الكود بالربط المهيكل (الصعوبة ⭐⭐)

CPP
#include <iostream>
#include <map>
#include <string>

int main() {
	std::map<int, std::string> students = {{1, "Zhang San"}, {2, "Li Si"}};
	
	// C++17: الربط المهيكل لاجتياز map
	for (const auto& [id, name] : students) {
		std::cout << id << ": " << name << std::endl;
	}
	
	return 0;
}
▶ جرّب الكود

الخرج:

TEXT 📖 للعرض فقط
1: Zhang San
2: Li Si

▶ مثال 3: استنتاج النوع auto (الصعوبة ⭐)

CPP
#include <iostream>
#include <vector>

int main() {
    auto x = 10;           // int
    auto y = 3.14;         // double
    auto name = "Hello";   // const char*
    
    std::vector<int> nums = {1, 2, 3, 4, 5};
    auto it = nums.begin(); // vector<int>::iterator
    
    std::cout << "x = " << x << std::endl;
    std::cout << "y = " << y << std::endl;
    std::cout << "name = " << name << std::endl;
    
    return 0;
}
▶ جرّب الكود

الخرج:

TEXT 📖 للعرض فقط
x = 10
y = 3.14
name = Hello

الخرج المتوقع:

TEXT 📖 للعرض فقط
x = 10
y = 3.14
name = Hello

❓ أسئلة شائعة

س هل يجب أن أستخدم أحدث معيار؟
ج ليس بالضرورة. ضع في اعتبارك: - دعم المترجم - إلمام الفريق - متطلبات المشروع

س كيف أفعّل C++17/20؟
ج أضف علامات عند التجميع: bash g++ -std=c++17 main.cpp g++ -std=c++20 main.cpp

س ما الجديد في C++23؟
ج - مكتبة قياسية معيارية - مكتبة الشبكات - المزيد من خوارزميات النطاقات

📖 ملخص

المعيار الميزات الرئيسية
C++17 الربط المهيكل، if constexpr، تعابير الطي
C++20 المفاهيم، النطاقات، الكوروتينات، الوحدات

📝 تمارين

  1. أساسي (الصعوبة ⭐): أعد كتابة مقطع كود C++ قديم (بأنواع صريحة، for تقليدي، NULL) باستخدام auto وfor المدعوم بنطاق وnullptr.

  2. متوسط (الصعوبة ⭐⭐): استخدم الربط المهيكل (C++17) لفك قيمة إرجاع pair أو tuple، وقارنها بالطريقة التقليدية .first/.second.

  3. متقدم (الصعوبة ⭐⭐⭐): استخدم if constexpr (C++17) لتنفيذ تفرع وقت التجميع — اكتب قالب دالة يطبق منطق معالجة مختلف للأنواع الصحيحة والأنواع العائمة.



الدرس التالي: تحسين الأداء (#49)

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%