Bagaimana cara melemparkan int ke enum di C ++?

222

Bagaimana cara melemparkan int ke enum di C ++?

Sebagai contoh:

enum Test
{
    A, B
};

int a = 1;

Bagaimana cara saya mengonversi auntuk mengetik Test::A?

pengguna1509260
sumber
1
Link Perhatikan bahwa tidak peduli apakah int cocok dengan salah satu konstanta dari jenis enum; konversi tipe selalu ilegal.
Iwaz
3
Saya percaya bahwa jika Anda ingin melakukan casting ke Test :: A nilai int aharus 0, karena Test :: A memiliki nilai implisit 0 dan Test :: B memiliki nilai implisit 1. Kecuali jika fakta casting khusus untuk Test :: A adalah selain intinya ...
JohnRDOrazio

Jawaban:

243
int i = 1;
Test val = static_cast<Test>(i);
Andrew
sumber
21
otomatis val = static_cast <Test> (i); // C ++ 11
Mitch
3
@ Nyalakan apa yang saya dapatkan untuk menggunakan autodalam hal ini? Apakah ada peningkatan kinerja?
Frederico Pantuzza
2
Tidak ada peningkatan kinerja. Compiler hanya menyimpulkan tipe secara otomatis jika Anda tentukan dengan "otomatis". Jika Anda memutuskan untuk mengubah nama enum Anda di masa mendatang, Anda akan memodifikasi kode Anda lebih sedikit karena kompiler akan secara otomatis menyimpulkan nama jenis yang benar.
Aydin Özcan
74
Test e = static_cast<Test>(1);
bames53
sumber
10
MSDN: Operator static_cast dapat secara eksplisit mengkonversi nilai integral ke tipe enumerasi. Jika nilai tipe integral tidak berada dalam kisaran nilai enumerasi, nilai enumerasi yang dihasilkan tidak terdefinisi.
Kirill Kobelev
1
@ KirillKobelev jika nilai integral dapat diwakili oleh tipe enum yang mendasarinya maka enum yang dihasilkan harus memiliki nilai itu. Kalau tidak, nilai enum yang dihasilkan akan menjadi nilai apa pun yang dihasilkan dari mengubah ekspresi menjadi tipe dasar enum. Jika VC ++ melakukan sesuatu yang berbeda maka saya pikir itu tidak sesuai.
bames53
2
apa yang harus dilakukan oleh kompiler konforman, jika enum memiliki nilai {1,3,5} dan upaya kode untuk melakukan <static_cast> dari nilai 2. Bagaimana perbedaan dari C-cast?
Kirill Kobelev
6
@ KirillKobelev Saya tidak menggunakan static_cast karena ia melakukan sesuatu yang berbeda dari pemain gaya C, saya menggunakan static_cast karena pemain C ++ secara stylistically lebih disukai daripada pemain C.
bames53
4
@KirillKobelev " jika enum memiliki nilai {1,3,5} " Tidak The pencacahan tipe tidak dapat dibatasi hanya 3 nilai-nilai ini mungkin: {1,3,5} adalah pencacah (bernama nilai-nilai pencacahan), tidak pencacahan itu sendiri . Jika 1,3,5 adalah nilai enumerasi yang mungkin , maka 2. adalah.
curiousguy
25

Kode Anda

enum Test
{
    A, B
}

int a = 1;

Larutan

Test castEnum = static_cast<Test>(a);
pengguna1515687
sumber
45
Merupakan ide bagus untuk menggunakan pemeran yang paling ketat yang Anda bisa, dan hindari pemeran gaya C sama sekali, untuk memberi kompiler itu peluang terbaik dalam mendeteksi kesalahan. static_castakan menjadi pemain yang lebih baik di sini.
Mike Seymour
4
@ Mike Seymour, masalahnya adalah cast statis tidak memiliki perbedaan dari cast-C dalam hal ini. Bagaimana dan kesalahan apa yang bisa dideteksi ???
Kirill Kobelev
7
@ KirillKobelev: Masalahnya adalah para pemeran C-style tidak eksplisit. Itu bisa sama dengan a static_cast, tetapi bisa juga menjadi const_castatau bahkan lebih buruk, reinterpret_castatau bahkan kombinasi dari mereka. Bahkan jika Anda tahu sekarang apa yang akan menurun, seandainya Anda berubah ake tipe lain di kemudian hari, itu bisa menjadi tipe perubahan casting tanpa Anda mendapatkan sebanyak peringatan, Anda tidak menginginkan itu.
KillianDS
4
@KillianDS " Andaikan Anda mengubah tipe yang lain nanti " tipe yang mana?
curiousguy
2
Ya, mereka atau pemeran implisit jika tersedia. Jauh lebih jelas untuk apa maksud para pemeran itu.
KillianDS
8

Memutar pertanyaan penutup, "bagaimana cara mengkonversi tipe Test::A" daripada menjadi kaku tentang persyaratan untuk memiliki pemain di sana, dan menjawab beberapa tahun terlambat hanya ini tampaknya menjadi pertanyaan populer sepertinya tidak ada orang lain yang telah menyebutkan alternatif , sesuai standar C ++ 11:

5.2.9 Pemain statis

... sebuah ekspresi edapat secara eksplisit dikonversi ke tipe T menggunakan a static_castdari formulir static_cast<T>(e)jika deklarasi T t(e);terbentuk dengan baik, untuk beberapa variabel temporer yang diciptakan t(8.5). Efek dari konversi eksplisit seperti itu sama dengan melakukan deklarasi dan inisialisasi dan kemudian menggunakan variabel sementara sebagai hasil dari konversi.

Oleh karena itu langsung menggunakan formulir t(e)juga akan berfungsi, dan Anda mungkin lebih suka kerapian:

auto result = Test(a);
Tommy
sumber
solusi ini berfungsi jika opsi kompiler diblokir static_cast <> (pemeriksaan semantik). Bukannya masuk akal bagiku, tapi masih rapi.
Tuan Buisson
1

Test castEnum = static_cast<Test>(a-1);akan memberikan a ke A. Jika Anda tidak ingin substruktur 1, Anda dapat mendefinisikan ulang enum:

enum Test
{
    A:1, B
};

Dalam hal ini `Test castEnum = static_cast (a); ' dapat digunakan untuk melemparkan ke A.

kosolapyj
sumber