Misalkan kita memiliki yang enum
seperti berikut:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Saya ingin membuat instance dari ini enum
dan menginisialisasi dengan nilai yang tepat, jadi saya lakukan:
Days day = Days.Saturday;
Sekarang saya ingin memeriksa variabel atau instance saya dengan enum
nilai yang ada , jadi saya lakukan:
if (day == Days.Saturday)
{
std::cout << "Ok its Saturday";
}
Yang memberi saya kesalahan kompilasi:
galat: ekspresi primer yang diharapkan sebelum '.' token
Jadi untuk menjadi jelas, apa perbedaan antara mengatakan:
if (day == Days.Saturday) // Causes compilation error
dan
if (day == Saturday)
?
Apa yang sebenarnya dimaksud oleh kedua hal ini, di mana yang OK dan yang satu menyebabkan kesalahan kompilasi?
Jawaban:
Kode ini salah:
Karena
Days
bukan ruang lingkup, atau objek. Itu adalah tipe. Dan Tipe sendiri tidak memiliki anggota. Apa yang Anda tulis sama denganstd::string.clear
.std::string
adalah tipe, jadi Anda tidak dapat menggunakannya.
. Anda menggunakan.
pada contoh dari sebuah kelas.Sayangnya, enum itu ajaib dan analoginya berhenti sampai di situ. Karena dengan kelas, Anda bisa melakukan
std::string::clear
untuk mendapatkan pointer ke fungsi anggota, tetapi di C ++ 03,Days::Sunday
tidak valid. (Yang menyedihkan). Ini karena C ++ (agak) mundur kompatibel dengan C, dan C tidak memiliki ruang nama, jadi enumerasi harus berada dalam ruang nama global. Jadi sintaksnya sederhana:Untungnya, Mike Seymour mengamati bahwa ini telah dibahas dalam C ++ 11. Ubah
enum
keenum class
dan itu mendapatkan ruang lingkupnya sendiri; jadiDays::Sunday
tidak hanya valid, tetapi merupakan satu - satunya cara untuk mengaksesSunday
. Hari hari menyenangkan!sumber
enum
keenum class
dan itu mendapatkan ruang lingkupnya sendiri; jadiDays::Sunday
tidak hanya valid, tetapi merupakan satu-satunya cara untuk mengaksesSunday
. Hari hari menyenangkan!'.' token
dandot operator
, selain itu token dan bukan operator, dan itu menunjukkan simbol yang tepat, bukan nama.enum
, Anda tidak dapat menggunakan cakupan, atau lingkup global (::Saturday
). Jika Anda memilikienum class
(yang merupakan hal yang sangat berbeda), maka Anda harus menggunakannyaDays::Saturday
.Ini akan cukup untuk mendeklarasikan variabel enum Anda dan membandingkannya:
sumber
Days
bukan ruang lingkup, atau objek. Itu adalah tipe. Dan Tipe sendiri tidak memiliki anggota.std::string.clear
juga gagal dikompilasi karena alasan yang sama.enum class
ruang lingkup ( , baru pada tahun 2011) memiliki cakupannya sendiri, dan diakses menggunakan operator lingkupDays::Saturday
,. Operator akses anggota (.
) hanya digunakan untuk mengakses anggota kelas.Banyak dari ini seharusnya memberi Anda kesalahan kompilasi.
Sekarang,
Saturday
,Sunday
, dll dapat digunakan sebagai konstanta telanjang tingkat atas, danDays
dapat digunakan sebagai tipe:Dan juga nanti, untuk menguji:
Ini
enum
nilai-nilai seperti konstanta telanjang - mereka un -scoped - dengan sedikit bantuan ekstra dari compiler: (kecuali jika Anda menggunakan C ++ 11 kelas enum ) mereka tidak dikemas seperti objek atau struktur anggota misalnya, dan Anda tidak dapat merujuk kepada mereka sebagai anggota dariDays
.Anda akan mendapatkan apa yang Anda cari dengan C ++ 11 , yang memperkenalkan
enum class
:Perhatikan bahwa C ++ ini sedikit berbeda dari C dalam beberapa cara, salah satunya adalah bahwa C membutuhkan penggunaan
enum
kata kunci saat mendeklarasikan variabel:sumber
Anda dapat menggunakan trik untuk menggunakan cakupan sesuai keinginan, cukup deklarasikan enum dengan cara:
sumber
Daripada menggunakan banyak pernyataan if, enum cocokkan diri mereka untuk berganti pernyataan
Saya menggunakan beberapa kombinasi enum / switch di pembangun tingkat yang saya bangun untuk permainan saya.
EDIT: Hal lain, saya melihat Anda ingin sintaks mirip dengan;
Anda dapat melakukan ini di C ++:
Ini adalah contoh yang sangat sederhana:
EnumAppState.h
Somefile.cpp
sumber
Jika Anda masih menggunakan C ++ 03 dan ingin menggunakan enums, Anda harus menggunakan enums di dalam namespace. Misalnya:
Anda dapat menggunakan enum di luar namespace seperti,
sumber
Anda mencari enumerasi yang sangat diketik , fitur yang tersedia dalam standar C ++ 11 . Itu mengubah enumerasi menjadi kelas dengan nilai lingkup.
Menggunakan contoh kode Anda sendiri, itu adalah:
Menggunakan
::
sebagai pengakor enumerasi akan gagal jika menargetkan standar C ++ sebelum C ++ 11. Tetapi beberapa kompiler lama tidak mendukungnya, juga beberapa IDE hanya mengganti opsi ini, dan menetapkan C ++ std yang lama.Jika Anda menggunakan GCC, aktifkan C + 11 dengan -std = c ++ 11 atau -std = gnu11 .
Berbahagialah!
sumber
enum class Days { ...
.Ini seharusnya tidak berfungsi di C ++:
Hari bukanlah ruang lingkup atau objek yang berisi anggota yang dapat Anda akses dengan operator titik. Sintaks ini hanya sebuah C # -ism dan tidak sah di C ++.
Microsoft telah lama memelihara ekstensi C ++ yang memungkinkan Anda untuk mengakses pengidentifikasi menggunakan operator lingkup:
Tapi ini non-standar sebelum C ++ 11. Dalam C ++ 03 pengidentifikasi yang dideklarasikan dalam enum hanya ada dalam lingkup yang sama dengan tipe enum itu sendiri.
C ++ 11 membuatnya sah untuk memenuhi syarat pengidentifikasi enum dengan nama enum, dan juga memperkenalkan kelas enum, yang menciptakan ruang lingkup baru untuk pengidentifikasi alih-alih menempatkan mereka dalam lingkup sekitarnya.
sumber
Sayangnya, elemen enum bersifat 'global'. Anda mengaksesnya dengan melakukan
day = Saturday
. Itu berarti bahwa Anda tidak dapat memilikienum A { a, b } ;
danenum B { b, a } ;
karena mereka berada dalam konflik.sumber
enum class
di C ++ 11, yaitu. Sebelum itu, Anda harus membuat kelas dummy.Sementara C ++ (tidak termasuk C ++ 11) memiliki enum, nilai-nilai di dalamnya "bocor" ke namespace global.
Jika Anda tidak ingin bocor (dan jangan PERLU menggunakan tipe enum), pertimbangkan hal berikut:
sumber
Enum di C ++ seperti integer yang ditutupi oleh nama yang Anda berikan, ketika Anda mendeklarasikan nilai enum Anda (ini bukan definisi hanya petunjuk bagaimana cara kerjanya).
Tetapi ada dua kesalahan dalam kode Anda:
enum
semua huruf kecilDays.
sebelum hari Sabtu.if (day == YourClass::Saturday){}
sumber
Saya pikir masalah root Anda adalah penggunaan
.
alih-alih::
, yang akan menggunakan namespace.Mencoba:
sumber
Days::
ruang lingkup seperti dalam contoh Anda, Anda harus menentukan enumerasi denganenum class Days
dan menggunakan C ++ 03 + ekstensi Microsoft atau C ++ 11.-std=c++98
atau-std=c++03
. Dentang cukup jelas:warning: use of enumeration in a nested name specifier is a C++11 extension
.Jika kita menginginkan keamanan tipe yang ketat dan lingkup enum, penggunaannya
enum class
bagus di C ++ 11.Jika kami harus bekerja di C ++ 98, kami dapat menggunakan saran yang diberikan oleh
InitializeSahib
,San
untuk mengaktifkan enum yang dicakup.Jika kita juga menginginkan keamanan tipe yang ketat, kode tindak dapat mengimplementasikan sesuatu seperti
enum
.Kode dimodifikasi dari contoh Bulan kelas di buku Efektif C ++ 3: Butir 18
sumber
Pertama-tama, buat 'E' di enum, 'e' sebagai huruf kecil.
Kedua, masukkan nama tipe 'Days' di 'Days.Saturday'.
Ketiga ... beli sendiri buku C ++ yang bagus.
sumber