0Pricing
C++ Academy · درس

أنماط enable_if

قيّد القوالب بالطريقة التقليدية

أنماط enable_if درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.

ما هي enable_if؟

إن std::enable_if سمة صغيرة تعرّف عضوًا باسم type بصورة شرطية. عندما يكون الشرط صحيحًا، يكون النوع موجودًا؛ وعندما يكون خطأً، يُحذف القالب المحيط عبر SFINAE.

  • توجد في <type_traits>.
  • وهي الأداة التقليدية لتقييد القوالب.
#include <iostream>
#include <type_traits>

template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
doubleIt(T v) { return v * 2; }

int main() {
    std::cout << doubleIt(21) << '\n';
    return 0;
}

كيف تعمل؟

تكون enable_if<Cond, T>::type مساويةً لـ T فقط عندما تكون Cond صحيحة. وإذا كانت خاطئة، فلا يوجد عضو باسم type، ولذلك يفشل الاستبدال.

#include <iostream>
#include <type_traits>

int main() {
    std::cout << std::boolalpha;
    std::cout << std::is_same<std::enable_if<true, int>::type, int>::value << '\n';
    return 0;
}

enable_if في نوع الإرجاع

الموضع الأكثر شيوعًا هو نوع الإرجاع. ولا تكون الدالة موجودة إلا عندما يتحقق الشرط.

#include <iostream>
#include <type_traits>

template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
half(T v) { return v / 2; }

int main() {
    std::cout << half(5.0) << '\n';
    return 0;
}

enable_if كمعامل قالب

يضع أسلوب آخر enable_if في معامل قالب ذي قيمة افتراضية، مما يحافظ على نظافة نوع الإرجاع.

#include <iostream>
#include <type_traits>

template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
T triple(T v) { return v * 3; }

int main() {
    std::cout << triple(4) << '\n';
    return 0;
}

الاختصار enable_if_t

أضافت C++14 الاسم البديل std::enable_if_t<Cond, T>، بحيث يمكنك تجنب الصياغة الزائدة typename ...::type.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value, T>
negate(T v) { return -v; }

int main() {
    std::cout << negate(8) << '\n';
    return 0;
}

إقران تحميلين زائدين

وفر شروطًا متكاملة بحيث يكون أحد التحميلين الزائدين صالحًا تمامًا لأي نوع، من دون أي التباس.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value, const char*>
category() { return "integer"; }

template <typename T>
std::enable_if_t<!std::is_integral<T>::value, const char*>
category() { return "non-integer"; }

int main() {
    std::cout << category<int>() << ' ' << category<double>() << '\n';
    return 0;
}

دمج الشروط

استخدم العوامل المنطقية مع قيم السمات للتعبير عن قيود أكثر تعقيدًا، مثل «تكاملي وموقّع».

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, T>
magnitude(T v) { return v < 0 ? -v : v; }

int main() {
    std::cout << magnitude(-12) << '\n';
    return 0;
}

تقييد مُنشئ

يمكنك وضع enable_if في معامل قالب المُنشئ للسماح باستخدامه فقط مع الأنواع المتوافقة.

#include <iostream>
#include <type_traits>

struct Wrapper {
    int value;
    template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
    Wrapper(T v) : value(static_cast<int>(v)) {}
};

int main() {
    Wrapper w(42);
    std::cout << w.value << '\n';
    return 0;
}

مأزق معامل القالب الافتراضي

يُنظر إلى تحميلين زائدين يختلفان فقط في معامل قالب enable_if ذي القيمة الافتراضية على أنهما إعادة تعريف. اجعلهما بصيغتين مختلفتين، كأن تضع أحد الشرطين في نوع الإرجاع.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
printKind() { std::cout << "int\n"; }

template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
printKind() { std::cout << "float\n"; }

int main() {
    printKind<int>();
    printKind<double>();
    return 0;
}

مقارنة بالمفاهيم

تستبدل المفاهيم في C++20 معظم استخدامات enable_if بصياغة أوضح بكثير، لكن enable_if تظل ضرورية في الشيفرة السابقة لـ C++20 وفي بعض الحالات الخاصة.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T>
square(T v) { return v * v; }

int main() {
    std::cout << square(6) << ' ' << square(1.5) << '\n';
    return 0;
}

مثال كامل

اجمع كل الأجزاء: عائلة دوال تُنسّق الأعداد الصحيحة والأعداد العشرية بطرق مختلفة، ويُختار بينها في وقت الترجمة.

#include <iostream>
#include <type_traits>

template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
format(T v) { std::cout << "int[" << v << "]\n"; }

template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
format(T v) { std::cout << "float(" << v << ")\n"; }

int main() {
    format(10);
    format(3.5);
    return 0;
}

تحقق سريع

اختبر مدى فهمك لـ enable_if.

مراجعة

لقد تعلمت الأنماط التقليدية لـ enable_if:

  • تعرّف ::type فقط عندما يكون الشرط صحيحًا، مما يتيح SFINAE
  • توضع في نوع الإرجاع أو في معامل قالب ذي قيمة افتراضية
  • استخدم الاسم البديل enable_if_t وادمج السمات باستخدام العوامل المنطقية
  • تحل المفاهيم محلها في C++20، لكنها ما تزال مستخدمة على نطاق واسع

وبذلك يكتمل مقرر تخصيص القوالب وSFINAE.

الأسئلة الشائعة

هل درس «أنماط enable_if» مجاني؟

نعم — نص درس «أنماط enable_if» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.

ماذا ستتعلم في «أنماط enable_if»؟

قيّد القوالب بالطريقة التقليدية تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟

لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «أنماط enable_if»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟

نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. التخصيص الكامل
  2. التخصيص الجزئي
  3. SFINAE
  4. أنماط enable_if
← العودة إلى C++ Academy