2012-03-24 39 views
16

Nếu tôi có một C++ enum:Làm thế nào để thay đổi kiểu số nguyên được sử dụng bởi một enum (C++)?

enum Foo 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

Làm thế nào để nói với trình biên dịch sử dụng một uint16_t để thực sự lưu trữ các giá trị của enum?

EDIT: GCC có hỗ trợ tính năng này khi triển khai C++ 11 không?

+1

@YochaiTimmer, tiêu chuẩn đã thay đổi và chủ đề trên liên kết không nói về 'enum class' – Lol4t0

+0

@YochaiTimmer: Không hề. Tôi muốn biết nếu tôi có thể thay đổi enum để lưu trữ các giá trị của nó nội bộ với một 'uint16_t', không phải là nó có cùng kích thước với' int'. – Linuxios

Trả lời

23

Bạn không thể làm điều này trong C++ 98/03 . C++ 11 không cho phép bạn làm điều đó, và mà khôngenum class đường đi mọi người khác dường như luôn nói với bạn:

enum EnumType : uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

lần nữa, bạn không cần phải sử dụng enum class. Đó không phải là ý tưởng tồi, nhưng bạn không .


có hỗ trợ GCC tính năng này trong việc thực hiện của C++ 11?

Which version of GCC? Dường như GCC 4.4 đã thêm chức năng này, nhưng có lẽ bạn nên xem xét các phiên bản gần đây hơn, chỉ vì mục đích ổn định.

+0

Tôi đã tự hỏi bản thân mình. Điểm khác biệt duy nhất là 'enum class' tạo ra một phạm vi mới, trong khi' enum' thì không. – chris

+3

@chris: Không, có một số khác biệt giữa 'enum class' và' enum'. Cả hai tạo ra phạm vi (ở trên 'Bar' có thể được truy cập với' EnumType :: Bar'), nhưng chỉ có 'class' phiên bản * lực * bạn sử dụng enum scoped. Ngoài ra, các biến 'enum class' không * ngầm định * chuyển đổi các số nguyên thành kiểu liệt kê. Vì vậy, bạn phải vượt qua một điều tra thực sự của các loại chính xác, hoặc bạn phải thực hiện một diễn viên rõ ràng. Điều này bổ sung thêm * nhiều * loại an toàn hơn. –

+0

Ồ, tôi nhận được quan điểm của mình từ một câu hỏi khác về SO: http://stackoverflow.com/questions/441552/scope-resolution-operator-on-enums-a-compiler-specific-extension Đối với điểm thứ hai của bạn, tôi chỉ đơn giản là chưa bao giờ nghe về điều đó. Cảm ơn bạn đã có kiến ​​thức miễn phí :) – chris

5

Với c++11 bây giờ bạn có enum class, cho phép bạn thiết lập loại cơ bản một cách rõ ràng:

enum class Foo: uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 
13

Trong C++ 11, bạn có thể làm điều đó:

enum class Foo : uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

Sau đó, bạn có thể cũng know the underlying type of the enum là:

#include <type_traits> 

std::underlying_type<Foo>::type v = 10; //v is uint16_t 
+3

+1 để thêm truy vấn 'basic_type'. –

5

Với pre-C++ 2011 bạn có thể buộc một lưu trữ tối thiểu bằng cách sử dụng một loạt phù hợp của các giá trị:

enum foo { 
    v0 = 0, 
    vmax = 32767 
}; 

Tôi nghĩ rằng trình biên dịch là tự do lựa chọn hoặc là một dấu hiệu hay một kiểu dữ liệu integer unsigned như loại cơ bản. Phạm vi trên thực thi rằng biểu diễn sử dụng ít nhất short vì nó nằm bên dưới số nguyên. Làm cho nó thậm chí lớn hơn có thể làm cho nó sử dụng long thay thế. Tất nhiên, điều này chỉ buộc một phạm vi tối thiểu và trình biên dịch là miễn phí để chọn một phạm vi lớn hơn. Ngoài ra, với định nghĩa trên, bạn không được phép đi ra ngoài phạm vi [0, 32767]: nếu bạn thực sự cần một phạm vi 16 bit (ít nhất), bạn cần sử dụng các giá trị tương ứng).

+1

Thực tế, cũng có một hạn chế về kích thước của loại cơ bản. [dcl.enum]/6 precises: ngoại trừ loại cơ bản không được lớn hơn 'int' trừ khi giá trị của một điều tra viên không thể phù hợp trong một' int' hoặc 'unsigned int'. –

Các vấn đề liên quan