سؤال

ولقد كنت تحاول أن تقرأ قليلا من مستوى C ++ لمعرفة كيف عمل التعداد في. هناك في الواقع هناك أكثر مما كنت اعتقد في البداية.

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

enum class color { red, green, blue};  // these are int

لالتعدادات unscoped، فإنه يبدو وكأنه نوع الأساسي يمكن أن يكون أي نوع لا يتجزأ من شأنها أن تعمل، وأنه لن يكون أكبر من عدد صحيح، إلا أنه يجب أن يكون.

enum color { red, green, blue};  // underlying type may vary

ومنذ ليست موحدة نوع الكامن وراء enumarations unscoped، ما هي أفضل طريقة للتعامل مع حالات تسلسل واحد؟ حتى الآن، لقد تم تحويل لint عند كتابة ثم تسلسل إلى int ووضع بلدي متغير enum في التحول عند القراءة، ولكن يبدو عالي الكعب قليلا. هل هناك طريقة أفضل؟

enum color { red, green, blue };
color c = red;
// to serialize
archive << (int)c;
// to deserialize
int i;
archive >> i;
switch(i) {
  case 0: c = red; break;
  case 1: c = green; break;
  case 2: c = blue; break;
}
هل كانت مفيدة؟

المحلول

وأنا لم أقرأ أي C ++ 0X الاشياء لذلك لا يمكن التعليق على ذلك.

وأما بالنسبة للتسلسل، أنت لا تحتاج إلى التبديل عند قراءة التعداد مرة أخرى في - مجرد يطرح للنوع التعداد

ولكن، أنا لا يلقي عند الكتابة إلى الدفق. هذا هو لأنني في كثير من الأحيان تريد أن تكتب عامل << لالتعداد حتى أتمكن من اللحاق القيم السيئة أثناء كتابة، أو أستطيع أن تقرر بعد ذلك لكتابة سلسلة بدلا من ذلك.

enum color { red, green, blue };
color c = red;

// to serialize
archive << c;    // Removed cast

// to deserialize
int i;
archive >> i;
c = (color)i;    // Removed switch

نصائح أخرى

الطبقة التعداد C ++ 0X ميزة، أنه غير موجود في C ++ 03.

<اقتباس فقرة>   

في مستوى C ++، التعدادات ليست من النوع الآمن. فهي صحيحة على نحو فعال، حتى عندما يكتب تعداد متميزة. وهذا يسمح للمقارنة بين قيمتين تعداد أنواع التعداد المختلفة. سلامة الوحيدة التي توفر C ++ 03 هي أن عددا صحيحا أو قيمة من نوع التعداد واحدة لا يتم تحويل ضمنيا إلى نوع التعداد آخر. بالإضافة إلى ذلك، ونوع لا يتجزأ الأساسية، وحجم عدد صحيح، لا يمكن تحديد بشكل واضح. هو تنفيذ محددة. وأخيرا، وراقب قيم التعداد إلى نطاق إرفاق. وبالتالي، فإنه ليس من الممكن لمدة التعدادات منفصلة لديها أسماء الأعضاء مطابقة.   وC ++ 0X السماح لتصنيف خاص للتعداد الذي لديه أيا من هذه القضايا. هذا ما يعبر عنه باستخدام تعريف فئة التعداد

وأمثلة (من المادة ويكيبيديا):

enum Enum1;                   //Illegal in C++ and C++0x; no size is explicitly specified.
enum Enum2 : unsigned int;    //Legal in C++0x.
enum class Enum3;             //Legal in C++0x, because enum class declarations have a default type of "int".
enum class Enum4: unsigned int; //Legal C++0x.
enum Enum2 : unsigned short;  //Illegal in C++0x, because Enum2 was previously declared with a different type.

وأما بالنسبة للجزء التسلسل (الذي أعتقد أنه لم يكن جزءا من السؤال الأصلي)، وأنا أفضل أن إنشاء فئة المساعد الذي يترجم العناصر التعداد إلى سلسلة من تعادل (والعودة)، وأسماء وعادة ما تكون أكثر استقرارا من قيم الأعداد التي تمثل، كعناصر التعداد يمكن أن يكون (وأحيانا تكون) إعادة ترتيب دون تغيير السلوك التعليمات البرمجية.

وقررت إنشاء إجابة جديدة لأن بلدي كان عمر فوضوي للغاية. على أي حال أريد فقط أن أقول شيئا عن C ++ 11، حيث يمكنك الحصول على نوع الأساسي من تعداد باستخدام هذا واحد:

std::underlying_type_t<E>

ومن أجل الفائدة، وفكرة قرار الزائد. ولكن يرجى استخدام أسماء لتخزين التعداد، على النحو الذي اقترحهlothar.

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

char (& f(int) )[1];
char (& f(unsigned int) )[2];

char (& f(long) )[3];
char (& f(unsigned long) )[4];

char const* names[] = { 
    "int", "unsigned int", 
    "long", "unsigned long"
};

enum a { A = INT_MIN };
enum b { B = UINT_MAX };
enum c { C = LONG_MIN };
enum d { D = ULONG_MAX };

template<typename T> void print_underlying() {
    std::cout << names[sizeof(f(T()))-1] << std::endl;
}

int main() { 
    print_underlying<a>();
    print_underlying<b>();
    print_underlying<c>();
    print_underlying<d>();
}

وكان يطبع هذا واحد هنا:

int
unsigned int
int
unsigned int

وانها ليست ذات أهمية خاصة لهذه المشكلة التسلسل (منذ حجم البيانات تسلسل ليست ذات عرض ثابت، وهذا يمكن أن يسبب مشاكل عند تغيير التعداد ونوعه الأساسي)، ولكن من المثير للاهتمام بشكل عام لمعرفة نوع تخزين كلها سردا. هتاف!

#include <type_traits>

enum a { bla1, bla2 };
typedef typename std::underlying_type<a>::type underlying_type;

if (std::is_same<underlying_type, int>::value)
  std::cout << "It's an int!" << endl;
else if (std::is_same<underlying_type, unsigned int>::value)
  std::cout << "It's an uint!" << endl;

وأما فيما يتعلق enum class color: هل هذا C ++ / CLI (C ++ .NET) أو في المستقبل كود C ++ 0X

لالتسلسل، يمكن أن تحصل حجم التعداد مع sizeof(color) معرفة عدد بايت نسخها.

scroll top