التخصيص الجزئي
خصّص أنماط القوالب
التخصيص الجزئي درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.
ما التخصيص الجزئي؟
يخصص التخصيص الجزئي قالبًا لـعائلة من الأنواع التي تشترك في نمط معين، بدلًا من نوع واحد محدد بدقة.
- تدعمه قوالب الفئات فقط.
- تترك بعض المعاملات عامة.
#include <iostream>
template <typename T>
struct Traits { static const char* kind() { return "value"; } };
template <typename T>
struct Traits<T*> { static const char* kind() { return "pointer"; } };
int main() {
std::cout << Traits<int>::kind() << '\n';
std::cout << Traits<int*>::kind() << '\n';
return 0;
}مطابقة المؤشرات
يطابق النمط T* أي نوع مؤشر، مما يتيح لك التعامل مع جميع المؤشرات باستخدام تخصيص واحد.
#include <iostream>
template <typename T>
struct Deref { static T get(T v) { return v; } };
template <typename T>
struct Deref<T*> { static T get(T* p) { return *p; } };
int main() {
int x = 42;
std::cout << Deref<int>::get(7) << '\n';
std::cout << Deref<int*>::get(&x) << '\n';
return 0;
}لا يمكن تخصيص الدوال تخصيصًا جزئيًا
تدعم قوالب الفئات (والمتغيرات) التخصيص الجزئي فقط. أما مع الدوال، فتستخدم التحميل الزائد بدلًا منه.
#include <iostream>
template <typename T>
void show(T) { std::cout << "value\n"; }
template <typename T>
void show(T*) { std::cout << "pointer\n"; }
int main() {
int x = 0;
show(5);
show(&x);
return 0;
}تخصيص أحد المعاملين
عند وجود معاملات نوعية متعددة، يمكنك تثبيت أحدها وترك الآخر مفتوحًا، لمطابقة نمط عبر الأنواع.
#include <iostream>
template <typename A, typename B>
struct Pair { static const char* kind() { return "mixed"; } };
template <typename A>
struct Pair<A, A> { static const char* kind() { return "same types"; } };
int main() {
std::cout << Pair<int, double>::kind() << '\n';
std::cout << Pair<int, int>::kind() << '\n';
return 0;
}مطابقة المصفوفات
يمكنك مطابقة أنواع المصفوفات باستخدام نمط يلتقط نوع العنصر والحجم باعتباره معاملًا غير نوعي.
#include <iostream>
template <typename T>
struct Info { static int size() { return 1; } };
template <typename T, int N>
struct Info<T[N]> { static int size() { return N; } };
int main() {
std::cout << Info<int>::size() << '\n';
std::cout << Info<int[5]>::size() << '\n';
return 0;
}أنماط const
يمكن للتخصيص إزالة const أو اكتشافه عبر مطابقة const T كنمط.
#include <iostream>
template <typename T>
struct IsConst { static const bool value = false; };
template <typename T>
struct IsConst<const T> { static const bool value = true; };
int main() {
std::cout << std::boolalpha;
std::cout << IsConst<int>::value << '\n';
std::cout << IsConst<const int>::value << '\n';
return 0;
}يفوز التخصيص الأكثر تخصصًا
عندما يمكن لعدة تخصيصات أن تتطابق، يختار المترجم التخصيص الأكثر تخصصًا، أي النمط الأكثر تحديدًا.
#include <iostream>
template <typename T>
struct K { static int v() { return 0; } };
template <typename T>
struct K<T*> { static int v() { return 1; } };
template <>
struct K<int*> { static int v() { return 2; } };
int main() {
std::cout << K<double*>::v() << ' ' << K<int*>::v() << '\n';
return 0;
}أنماط المراجع
يمكنك أيضًا مطابقة أنواع المراجع، والتمييز بين المرجع والقيمة العادية.
#include <iostream>
template <typename T>
struct Cat { static const char* k() { return "value"; } };
template <typename T>
struct Cat<T&> { static const char* k() { return "lvalue ref"; } };
int main() {
std::cout << Cat<int>::k() << '\n';
std::cout << Cat<int&>::k() << '\n';
return 0;
}بناء سمات الأنواع
التخصيص الجزئي هو المحرك الذي يقف وراء سمات الأنواع. إليك تطبيقًا يدويًا لـ remove_pointer.
#include <iostream>
#include <type_traits>
template <typename T>
struct RemovePtr { using type = T; };
template <typename T>
struct RemovePtr<T*> { using type = T; };
int main() {
std::cout << std::boolalpha;
std::cout << std::is_same<RemovePtr<int*>::type, int>::value << '\n';
return 0;
}دمج الأنماط
يمكنك دمج الأنماط، مثل مطابقة مؤشر إلى قيمة ثابتة، للتعامل مع هياكل الأنواع متعددة الطبقات.
#include <iostream>
template <typename T>
struct Desc { static const char* k() { return "plain"; } };
template <typename T>
struct Desc<const T*> { static const char* k() { return "ptr to const"; } };
int main() {
std::cout << Desc<int>::k() << '\n';
std::cout << Desc<const int*>::k() << '\n';
return 0;
}سمة عملية للحاويات
استخدم تخصيصًا جزئيًا لاستخراج نوع العنصر من قالب يشبه الحاوية.
#include <iostream>
#include <type_traits>
template <typename C>
struct Element { using type = void; };
template <template <typename> class C, typename T>
struct Element<C<T>> { using type = T; };
template <typename T>
struct Box { T item; };
int main() {
std::cout << std::boolalpha;
std::cout << std::is_same<Element<Box<int>>::type, int>::value << '\n';
return 0;
}تحقق سريع
اختبر مدى فهمك للتخصيص الجزئي.
مراجعة
لقد تعلمت التخصيص الجزئي:
- يخصص قالب فئة لنمط من الأنواع مثل
T*أوconst T - تستخدم الدوال التحميل الزائد، لا التخصيص الجزئي
- يُختار الإصدار المطابق الأكثر تخصصًا
- يشكل الأساس لسمات الأنواع مثل
remove_pointer
بعد ذلك، ستتعلم SFINAE، وهي طريقة لتمكين الدوال فقط عندما يستوفي النوع الشروط.
الأسئلة الشائعة
هل درس «التخصيص الجزئي» مجاني؟
نعم — نص درس «التخصيص الجزئي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.
ماذا ستتعلم في «التخصيص الجزئي»؟
خصّص أنماط القوالب تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟
لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «التخصيص الجزئي»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟
نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- التخصيص الكامل
- التخصيص الجزئي
- SFINAE
- أنماط enable_if