حتى الآن تعاملنا في الغالب مع الأعداد والسلاسل النصية. ولنمذجة العالم الحقيقي، قد نحتاج إلى عدد محدود من القيم التي يمكن أن يأخذها المتغير. قد ترغب في نوع مخصص له بضع قيم مميزة بأسماء مميزة. على سبيل المثال، في مصنع ألواح التزلج، أن تكون مادة اللوح محصورة في اختيار واحد فقط من maple أو bamboo أو plastic.
يمكنك استخدام الأعداد الصحيحة لترميز تلك القيم، لكن سيتعين عليك كتابة كود إضافي للتحقق مما إذا كانت هناك قيمة غير صالحة تأتي من النظام للمادة.
يصعب تتبع معنى تلك الأرقام السحرية عبر الكود المصدري، كما أنها عرضة للخلط.
ويمكن استخدام enumerations لتشجيع كود معبّر وللحد من أخطاء المقارنة غير المقصودة.
المصطلح المحدد لهذا النوع من التعدادات هو scoped enumeration.
يعرض المقطع التالي كيفية كتابة enumeration من نوع DeckMaterial.
لاحظ الكلمة المفتاحية enum class وعلامة ; في نهاية التعريف:
enum class DeckMaterial {
maple,
bamboo,
plastic
};
الآن، انظر إلى دالة التسعير في متجر ألواح التزلج، ولاحظ عامل تحديد النطاق (::) الذي يحدد enumerator من enumeration:
double deck_price(double base_price, DeckMaterial material) {
if(material == DeckMaterial::plastic) {
return base_price * 0.9;
}
return base_price * 1.3;
}
تخيّل أن لديك enumeration ثانيًا لمادة العجلات:
enum class WheelMaterial {
steel,
clay,
plastic
};
رغم أن العجلات واللوح يمكن أن يكونا مصنوعين من plastic، فلا يمكن الخلط بينهما.
إنهما نوعان مختلفان: plastic من DeckMaterial وplastic من WheelMaterial.
سيكون لكل enumeration enumerators الخاصة به في نطاقه الخاص، أي namespace الخاص به.
ولهذا تُسمى scoped enumerations.
قد تظن أنه مع اسم مثل scoped ستوجد أيضًا تعدادات unscoped، وأنت محق في ذلك.
أصبحت Unscoped enumerations أقل شيوعًا لأنها تشترك جميعها في فضاء الأسماء العام نفسه.
وبسبب هذه المشاركة، لا يمكن أن يكون لديك unscoped enumerations اثنان يشتركان في enumerators نفسها مثل plastic في المثال أعلاه.
كما أن unscoped enumerations تُحوَّل ضمنيًا إلى أعداد صحيحة.
انظر إلى المثال التالي للحصول على نتيجة مفاجئة:
enum CitrusFruits {
lemons, // 0
oranges, //1
};
enum IceCream {
walnut, // 0
apples, // 1
};
bool comparison{apples == oranges};
// => true
// Example from above:
bool comparison{DeckMaterial::plastic == WheelMaterial::plastic};
// => Does not compile!
إذا أردت تحويل scoped enumerations إلى أعداد صحيحة، يمكنك استخدام static_cast<int>.