วิธีการใช้งาน int เพื่อ enum ใน C ++?


222

ฉันจะส่ง int ไปยัง enum ใน C ++ ได้อย่างไร

ตัวอย่างเช่น:

enum Test
{
    A, B
};

int a = 1;

ฉันจะแปลงaเป็นประเภทได้Test::Aอย่างไร


1
การเชื่อมโยงหมายเหตุว่ามันไม่สำคัญว่า int ตรงกับหนึ่งของค่าคงที่ประเภท enum นั้น การแปลงประเภทนั้นผิดกฎหมายเสมอ
Iwaz

3
ฉันเชื่อว่าหากคุณต้องการส่งการทดสอบ :: ค่าint aจะต้องเป็น 0 เนื่องจากการทดสอบ :: A มีค่าโดยนัยเป็น 0 และการทดสอบ :: B มีค่าโดยนัยที่ 1 เว้นแต่ความจริงของการหล่อ โดยเฉพาะสำหรับ Test :: A นั้นนอกเหนือจากจุด ...
JohnRDOrazio

คำตอบ:


243
int i = 1;
Test val = static_cast<Test>(i);

21
auto val = static_cast <Test> (i); // C ++ 11
Mitch

3
@ Mitch ฉันจะใช้อะไรautoในกรณีนี้ มีการปรับปรุงประสิทธิภาพหรือไม่?
Frederico Pantuzza

2
ไม่มีการปรับปรุงประสิทธิภาพ คอมไพเลอร์จะลดจำนวนประเภทโดยอัตโนมัติหากคุณระบุด้วย "อัตโนมัติ" หากคุณตัดสินใจที่จะเปลี่ยนชื่อ enum ของคุณในอนาคตคุณจะปรับเปลี่ยนรหัสของคุณให้น้อยลงเนื่องจากคอมไพเลอร์จะสรุปชื่อประเภทที่ถูกต้องโดยอัตโนมัติ
Aydin Özcan

74
Test e = static_cast<Test>(1);

10
MSDN: ตัวดำเนินการ static_cast สามารถแปลงค่าอินทิกรัลเป็นประเภทการแจงนับได้อย่างชัดเจน หากค่าของประเภทอินทิกรัลไม่ได้อยู่ในช่วงของค่าการแจงนับค่าการแจงนับที่ได้จะไม่ถูกกำหนด
Kirill Kobelev

1
@KirillKobelev หากค่าหนึ่งสามารถแสดงโดยชนิดพื้นฐานของ enum แล้ว enum ที่เกิดขึ้นจะต้องมีค่านั้น มิฉะนั้นค่า enum ที่ผลิตจะเป็นค่าใดก็ตามที่เป็นผลลัพธ์จากการแปลงนิพจน์เป็นชนิดพื้นฐานของ enum ถ้า VC ++ ทำสิ่งที่แตกต่างออกไปฉันคิดว่ามันไม่สอดคล้อง
bames53

2
สิ่งที่คอมไพเลอร์คอมไพเลอร์ควรทำอย่างไรถ้า enum มีค่า {1,3,5} และรหัสพยายามที่จะทำ <static_cast> จากมูลค่า 2 สิ่งที่จะแตกต่างจาก C-cast?
Kirill Kobelev

6
@KirillKobelev ฉันไม่ได้ใช้ static_cast เพราะมันทำอะไรที่แตกต่างจากนักแสดงสไตล์ C ฉันใช้ static_cast เพราะนักแสดง C ++ นั้นนิยมใช้ C cast มากกว่า
bames53

4
@KirillKobelev " ถ้า enum มีค่า {1,3,5} " ไม่ประเภทการแจงนับไม่สามารถ จำกัด เฉพาะค่าที่เป็นไปได้ 3 ค่าต่อไปนี้: {1,3,5} เป็นตัว แจงนับ (ระบุค่าการแจงนับ) ไม่ใช่การแจงนับเอง . หากเป็นไปได้ 1,3,5 แจงนับค่าแล้วเพื่อให้เป็น 2
curiousguy

25

รหัสของคุณ

enum Test
{
    A, B
}

int a = 1;

สารละลาย

Test castEnum = static_cast<Test>(a);

45
เป็นความคิดที่ดีที่จะใช้นักแสดงที่เข้มงวดที่สุดที่คุณสามารถทำได้และหลีกเลี่ยงการร่าย C สไตล์เพื่อให้คอมไพเลอร์เป็นโอกาสที่ดีที่สุดในการตรวจสอบข้อผิดพลาด static_castจะเป็นนักแสดงที่ดีกว่าที่นี่
Mike Seymour

4
@ ไมค์ซีมัวร์ปัญหาคือการที่คงหล่อไม่แตกต่างจาก C-cast ในกรณีนี้ วิธีการและสิ่งที่ผิดพลาดสามารถตรวจจับ ???
Kirill Kobelev

7
@KirillKobelev: ปัญหาคือการส่งแบบ C ไม่ชัดเจน มันอาจจะเท่ากับ a static_castแต่มันอาจจะเป็นconst_castหรือแย่กว่านั้นreinterpret_castหรืออาจเป็นการรวมกันของสิ่งเหล่านั้น แม้ว่าคุณจะรู้แล้วว่าสิ่งใดที่จะทำให้เสื่อมเสีย แต่สมมติว่าคุณเปลี่ยนaเป็นประเภทอื่นในภายหลังมันอาจเป็นประเภทของการเปลี่ยนแปลงที่ชี้ขาดได้โดยที่คุณไม่ได้รับคำเตือนเท่าที่ควร
KillianDS

4
@KillianDS " สมมติว่าคุณเปลี่ยนเป็นประเภทอื่นในภายหลัง " ประเภทใด
2012

2
ใช่ไม่ว่าจะเป็นสิ่งเหล่านั้นหรือการส่งโดยนัยหากมี มันชัดเจนมากขึ้นว่าเจตนาของนักแสดงคืออะไร
KillianDS

8

การหมุนคำถามปิด "ฉันจะแปลง a เป็นประเภทอย่างไรTest::A" แทนที่จะเข้มงวดกับความต้องการที่จะมีนักแสดงในนั้นและตอบคำถามเมื่อหลายปีที่ผ่านมาเพียงแค่นี้ดูเหมือนว่าจะเป็นคำถามยอดนิยมที่ไม่มีใครพูดถึงทางเลือกอื่น ตามมาตรฐาน C ++ 11:

5.2.9 ร่ายคงที่

... นิพจน์eสามารถแปลงเป็นประเภทได้อย่างชัดเจนT โดยใช้static_castแบบฟอร์มstatic_cast<T>(e)หากการประกาศ T t(e);มีรูปแบบที่ดีสำหรับตัวแปรชั่วคราวที่คิดค้นขึ้นt(8.5) ผลของการแปลงที่ชัดเจนนั้นเหมือนกับการประกาศและการเริ่มต้นจากนั้นใช้ตัวแปรชั่วคราวที่เป็นผลลัพธ์ของการแปลง

ดังนั้นการใช้แบบฟอร์มโดยตรงจะใช้t(e)งานได้และคุณอาจชอบมันเพื่อความเรียบร้อย:

auto result = Test(a);

วิธีการแก้ปัญหานี้ทำงานในกรณีที่ตัวเลือกคอมไพเลอร์บล็อก static_cast <> (ตรวจสอบความหมาย) ไม่ใช่ว่ามันสมเหตุสมผลสำหรับฉัน แต่ก็ยังเรียบร้อย
นาย Buisson

1

Test castEnum = static_cast<Test>(a-1);จะส่ง a ถึง A หากคุณไม่ต้องการโครงสร้างย่อย 1 คุณสามารถกำหนดใหม่enum:

enum Test
{
    A:1, B
};

ในกรณีนี้ `ทดสอบ castEnum = static_cast (a); ' สามารถใช้เพื่อส่ง a ถึง A

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.