2008-09-16 54 views
17

Có cách nào để có một enum 64 bit trong C + +? Trong khi refactoring một số mã tôi đã đi qua bó của #defines đó sẽ là tốt hơn như một enum, nhưng được lớn hơn 32 bit gây ra trình biên dịch để lỗi.64 bit enum trong C++?

Đối với một số lý do tôi nghĩ những điều sau đây có thể làm việc:

enum MY_ENUM : unsigned __int64 
{ 
    LARGE_VALUE = 0x1000000000000000, 
}; 
+0

Có lý do nào để chọn 'unsigned __int64' trên' uint64_t' không? Tôi nghĩ rằng 'uint64_t' được định nghĩa cho hầu như mọi nền tảng liên quan, nhưng' unsigned __int64' có vẻ như một định nghĩa cụ thể về nền tảng (phần cứng, trình biên dịch hoặc thậm chí là thư viện). – Johan

Trả lời

14

Tôi không nghĩ rằng có thể với C++ 98. Các đại diện cơ bản của enums là đến trình biên dịch. Trong trường hợp đó, bạn nên sử dụng:

const __int64 LARGE_VALUE = 0x1000000000000000L; 

Tính đến C++ 11, người ta có thể sử dụng các lớp enum để xác định các loại hình cơ bản của enum:

enum class MY_ENUM : unsigned __int64 { 
    LARGE_VALUE = 0x1000000000000000ULL 
}; 

Ngoài enum các lớp giới thiệu một phạm vi tên mới. Vì vậy, thay vì tham chiếu đến LARGE_VALUE, bạn sẽ tham chiếu MY_ENUM::LARGE_VALUE.

+0

Đây là những gì tôi sử dụng để kết thúc, nhưng tôi đã tò mò muốn xem liệu các bitum 64 bit là có thể, ngay cả với một phần mở rộng trình biên dịch cụ thể. – Rob

0

Một enum trong C++ có thể được bất kỳ loại tách rời. Bạn có thể, ví dụ, có một enum của ký tự. IE:

enum MY_ENUM 
{ 
    CHAR_VALUE = 'c', 
}; 

tôi sẽ giả này bao gồm __int64. Hãy thử chỉ

enum MY_ENUM 
{ 
    LARGE_VALUE = 0x1000000000000000, 
}; 

Theo commenter tôi, sixlettervariables, trong C các loại hình cơ bản sẽ là một int mọi khi, trong khi trong C++ loại cơ bản là bất cứ điều gì là đủ lớn để phù hợp với những giá trị bao gồm lớn nhất. Vì vậy, cả hai enums trên nên làm việc.

+1

@Doug T .: trong khi ANSI C quy định rằng các liệt kê là kích thước của kiểu dữ liệu 'int', ISO C++ quy định rằng các liệt kê có kích thước ít nhất là lớn như được yêu cầu để biểu diễn tất cả các giá trị. – user7116

1

Kể từ khi bạn đang làm việc trong C++, thay thế khác có thể

const __int64 LARVE_VALUE = ... 

này có thể được quy định trong một tập tin H.

+0

Tôi đã lừa 9 ký tự với lần thử đầu tiên. – Behrooz

2

Nếu trình biên dịch không hỗ trợ các bit enum 64 bit bằng cờ tổng hợp hoặc bất kỳ phương tiện nào khác, tôi nghĩ rằng không có giải pháp cho điều này.

Bạn có thể tạo ra một cái gì đó giống như trong một cái gì đó mẫu của bạn như:

namespace MyNamespace { 
const uint64 LARGE_VALUE = 0x1000000000000000; 
}; 

và sử dụng nó giống như một enum sử dụng

MyNamespace::LARGE_VALUE 

hoặc

using MyNamespace; 
.... 
val = LARGE_VALUE; 
+1

Và an toàn loại lỏng lẻo, mặc dù. –

+0

Unfortunatelly yes – INS

+2

Tốc độ cuộc trò chuyện của chúng tôi nhắc tôi về cờ tương ứng: D –

1

snipplet bạn mã là không phải tiêu chuẩn C++:

enum MY_ENUM: unsigned __int64

không có ý nghĩa.

sử dụng const __int64 thay vào đó, như Torlack gợi ý

+0

anh ta đã thấy nó trong một ngôn ngữ dấu ngoặc nhọn khác (ví dụ: C# hỗ trợ nó) hoặc trong tiêu chuẩn C++ sắp tới. –

17

C++ 11 hỗ trợ này, sử dụng cú pháp sau:

enum class Enum2 : __int64 {Val1, Val2, val3}; 
+0

Tôi đã gần rồi. Tôi phải đọc về cú pháp ': type' ở đâu đó. – Rob

+2

lưu ý rằng 'lớp' vẫn là tùy chọn. Nếu bạn muốn enum kiểu cũ, nhưng với một kiểu tùy chỉnh, bạn cũng có thể 'enum moo: long long {...}' –

4

Những câu trả lời đề cập đến __int64 bỏ lỡ vấn đề. Enum hợp lệ trong tất cả các trình biên dịch C++ có một loại tích phân 64 bit thực sự, tức là bất kỳ trình biên dịch C++ 11 nào, hoặc trình biên dịch C++ 03 với các phần mở rộng thích hợp. Các phần mở rộng cho C++ 03 như __int64 hoạt động khác nhau giữa các trình biên dịch, bao gồm cả sự phù hợp của nó như là một kiểu cơ sở cho enums.

0

Trong MSVC++ bạn có thể làm điều này:

enum MYLONGLONGENUM: __ Int64 {BIG_KEY = 0x3034303232303330, ...};

+2

sử dụng tốt hơn int64-max so với dự đoán tự nhiên kỳ diệu. –

5

Dự thảo hiện tại của cái gọi là C++0x, nó là n3092 nói trong 7.2 tờ khai Enumeration, đoạn 6:

Đó là thực hiện xác định mà loại không thể thiếu được sử dụng như các loại cơ bản ngoại trừ việc các loại cơ bản không được lớn hơn so với int trừ khi giá trị của điều tra không thể khớp với một int hoặc int chưa được ký.

Đoạn cùng cũng nói:

Nếu không có loại không thể thiếu thể đại diện cho tất cả các giá trị Enumerator, kiểu liệt kê là vô hình thành.

giải thích của tôi về phần 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 là nó hoàn toàn hợp lệ và an toàn để khởi Enumerator với giá trị số nguyên 64-bit miễn là có 64 loại số nguyên bit được cung cấp trong một triển khai C++ cụ thể.

Ví dụ:

enum MyEnum 
{ 
    Undefined = 0xffffffffffffffffULL 
}; 
+3

Nếu bạn không muốn đếm số f của mình, bạn chỉ có thể thực hiện 'Undefined = ~ 0x0ULL' –

1

Enum loại thường được xác định bởi các kiểu dữ liệu của initializer enum đầu tiên. Nếu giá trị vượt quá phạm vi cho kiểu dữ liệu không thể tách rời đó thì trình biên dịch C++ sẽ đảm bảo nó phù hợp bằng cách sử dụng kiểu dữ liệu tích phân lớn hơn. Nếu trình biên dịch thấy rằng nó không thuộc về bất kỳ kiểu dữ liệu tách rời nào thì trình biên dịch sẽ ném lỗi. Tham khảo: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Chỉnh sửa: Tuy nhiên, điều này hoàn toàn phụ thuộc vào kiến ​​trúc máy

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