Pertanyaan ini muncul di benak saya, ketika saya memiliki sesuatu seperti
enum Folders {FA, FB, FC};
dan ingin membuat berbagai wadah untuk setiap folder:
ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
(Menggunakan peta, ini jauh lebih elegan untuk digunakan std::map<Folders, ContainerClass*> m_containers;
:)
Tetapi untuk kembali ke pertanyaan awal saya: Bagaimana jika saya tidak ingin membuat kode keras ukuran array, adakah cara untuk mengetahui berapa banyak item yang ada di Folder? (Tanpa bergantung pada misalnya FC
menjadi item terakhir dalam daftar yang akan memungkinkan sesuatu seperti ContainerClass*m_containers[FC+1]
jika saya tidak salah.)
c++
count
enumeration
fuenfundachtzig
sumber
sumber
int(FA) | int(FB) | int (FC)
juga merupakan nilai legal untukFolders
variabel. Jika Anda mengukurm_containers
sehinggaFolders
variabel apa pun adalah indeks yang valid,[FC+1]
tidak akan cukup besar.Jawaban:
Sebenarnya tidak ada cara yang baik untuk melakukan ini, biasanya Anda melihat item tambahan di enum, yaitu
Jadi, Anda dapat melakukan:
Masih tidak terlalu bagus.
Tapi tentu saja Anda menyadari bahwa jumlah item dalam enum tidaklah aman, misalnya
jumlah item akan menjadi 4, tetapi nilai integer dari nilai enum akan keluar dari rentang indeks array. Menggunakan nilai enum untuk pengindeksan array tidak aman, Anda harus mempertimbangkan opsi lain.
edit: seperti yang diminta, membuat entri khusus lebih menonjol.
sumber
Untuk C ++, ada berbagai teknik enum tipe aman yang tersedia, dan beberapa di antaranya (seperti Boost.Enum yang diusulkan tetapi tidak pernah dikirimkan ) menyertakan dukungan untuk mendapatkan ukuran enum.
Pendekatan paling sederhana, yang berfungsi di C dan juga C ++, adalah mengadopsi konvensi mendeklarasikan nilai ... MAX untuk setiap jenis enum Anda:
Sunting : Mengenai
{ FA, FB, FC, Folders_MAX = FC}
versus{FA, FB, FC, Folders_MAX]
: Saya lebih suka menyetel nilai ... MAX ke nilai legal terakhir dari enum karena beberapa alasan:Folders_MAX
memberikan nilai enum semaksimal mungkin).Folders_MAX = FC
menonjol dari entri lain sedikit lebih (membuatnya sedikit lebih sulit untuk secara tidak sengaja menambahkan nilai enum tanpa memperbarui nilai maksimal, masalah yang direferensikan Martin York).sumber
enum Folders { FA, FB, FC, Folders_MAX }; ContainerClass *m_containers[Folders_MAX];
:?struct SomeEnum { enum type {FA, FB, FC, NB__};};
Bagaimana dengan ciri-ciri, dalam gaya STL? Misalnya:
menulis sebuah
spesialisasi (mungkin constexpr jika Anda menggunakan c ++ 11). Kemudian, dalam kode pengujian Anda, berikan pernyataan statis apa pun untuk mempertahankan batasan yang std :: numeric_limits :: max () = last_item.
sumber
std::numeric_limits<enum Foo>::max()
selalu mengembalikan nol ... (lihat pertanyaan untuk jawaban yang ditautkan) Diuji pada enum normal (enum Foo { ... }
), enum dengan petunjuk tipe (enum class Foo : uint8_t { ... }
) dengan gcc 5.2.0 @ Linux dan MinGW 4.9.3 @ Windows.std::numeric_limits<std::underlying_type<Foo>::type>::max()
, ini mengembalikan nilai maksimum dari tipe yang mendasarinya yaitu 0xFFFFFFFF untuk bilangan bulat 32-bit, yang tidak berguna dalam konteks ini.)namespace gx { enum struct DnaNucleobase : char { A, C, G, T }; }
Kemudian:namespace std { template<> struct numeric_limits<enum ::gx::DnaNucleobase> { typedef enum ::gx::DnaNucleobase value_type; static constexpr value_type max() { return value_type::T; } (...)
Danstd::cout << std::numeric_limits<::gx::DnaNucleobase>::max() << std::endl;
mencetak hasil yang diharapkan. Diuji dengan rasa gcc 5.2.1 dan 4.8 / 4.9.numeric_limits<T>::max()
. Satu-satunya hal yang dapat dikembalikan oleh fungsi secara wajar adalah nilai enumerasi tertinggi. Itu akan kembali2
, tetapi OP (dalam kasus khusus ini) akan membutuhkannya untuk kembali3
. Setelah Anda memiliki nilai non-default untuk enum (FB = 2057
), semua taruhan dibatalkan, bahkan tidak+ 1
dapat meretas kesalahan off-by-one. Jika adanumeric_limits<T>::number_of_elements_of_the_set()
(atau nama yang lebih pendek), itu bisa digunakan tanpa ambiguitas.Tambahkan entri, di akhir enum Anda, yang disebut Folders_MAX atau sesuatu yang serupa dan gunakan nilai ini saat menginisialisasi array Anda.
sumber
Saya suka menggunakan enum sebagai argumen untuk fungsi saya. Ini adalah cara yang mudah untuk memberikan daftar tetap "opsi". Masalah dengan jawaban pilihan teratas di sini adalah bahwa dengan menggunakan itu, klien dapat menentukan "opsi tidak valid". Sebagai spin off, saya sarankan melakukan hal yang pada dasarnya sama, tetapi gunakan int konstan di luar enum untuk menentukan jumlah mereka.
Ini tidak menyenangkan, tetapi ini adalah solusi yang bersih jika Anda tidak mengubah enum tanpa memperbarui konstanta.
sumber
Saya benar-benar tidak melihat cara apa pun untuk benar-benar mendapatkan jumlah nilai dalam pencacahan di C ++. Salah satu solusi yang disebutkan sebelumnya berfungsi selama Anda tidak menentukan nilai enumerasi Anda jika Anda menentukan nilai yang mungkin Anda hadapi dalam situasi di mana Anda membuat array terlalu besar atau terlalu kecil
dalam contoh tentang ini, hasilnya akan membuat larik 3 item saat Anda membutuhkan larik 5 item
dalam contoh tentang ini, hasilnya akan membuat array 301 item ketika Anda membutuhkan array yang terdiri dari 5 item
Cara terbaik untuk menyelesaikan masalah ini dalam kasus umum adalah dengan mengulang melalui pencacahan Anda tetapi itu belum sesuai standar sejauh yang saya tahu
sumber