2017-06-18 13 views
5

Tôi có thể xác định loại để sử dụng làm kiểu liệt kê cơ bản không? Một cái gì đó như thế này:Kiểu tùy chỉnh enum cơ bản

struct S { 
    S(int i) : value(i) {} 
    operator int() { return value; } 

    int value; 
}; 

enum E : S { 
    A, B, C 
}; 

Thông báo lỗi cho tôi biết rằng S phải là một loại tích phân. Tôi đã cố gắng chuyên std::is_integral như sau, nhưng có vẻ như trong bối cảnh này, "loại tích phân" thực sự có nghĩa là một trong những loại cơ bản.

namespace std { 
    template<> 
    struct is_integral<S> : public true_type {}; 
} 

Vì vậy, sử dụng bất kỳ phiên bản nào của C++, có cách nào để tạo loại tùy chỉnh chuyển thành loại không thể tách rời không?

Trả lời

2

Tôi có thể xác định loại để sử dụng làm loại liệt kê cơ bản không?

Bạn chỉ có thể sử dụng các loại tích phân để xác định enum s, không phải bất kỳ loại cũ nào.

Ví dụ, bạn có thể sử dụng

enum E : char { 
    A, B, C 
}; 

để chỉ giá trị của E sẽ loại char. Nhưng bạn không thể sử dụng

enum E : S { 
    A, B, C 
}; 

Từ C++11 Standard, 3.9.1/7:

loại bool, char, char16_t, char32_t, wchar_t, và các loại nguyên signed và unsigned được gọi chung là loại không thể thiếu. Từ đồng nghĩa cho loại tích phân là loại số nguyên.

+0

Vì vậy, "loại tích phân" trong ngữ cảnh này không liên quan gì đến ' std :: is_integral'? – Nelfeal

+0

Ví dụ bạn đã đăng sẽ là phiên bản lật đổ của mục đích 'std :: is_integral'. Tôi không chắc liệu có bất cứ điều gì trong ngôn ngữ để ngăn chặn điều đó không. –

+3

[Có vẻ như chuyên bất cứ điều gì trong '' là hành vi không xác định.] (Https://stackoverflow.com/questions/8513417/what-can-and-cant-i-specialize-in-the-std-namespace). Tôi nên nhìn kỹ hơn. Ngoài ra [this] (https://stackoverflow.com/questions/25345486/why-specializing-a-type-trait-could-result-in-undefined-behaviour) (nhờ HolyBlackCat). – Nelfeal

2

std :: is_integral kiểm tra xem T có phải là một loại không tách rời hay không. Cung cấp các thành viên giá trị không đổi tương đương với sự thật, nếu T là loại bool, char, char16_t, char32_t, wchar_t, short, int, long, long long, hoặc bất kỳ loại nguyên mở rộng thực hiện xác định, bao gồm bất kỳ ký, unsigned, và các biến thể đủ điều kiện cv. Nếu không, giá trị bằng false.

Đây là trích đoạn từ here. Điều này có nghĩa rằng một enum phải sử dụng một trong các loại sau đây:

bool, char, char16_t, char32_t, wchar_t, short, int, long, long long.

+0

[Điều đó không có nghĩa là bạn không thể chuyên 'is_integral'.] (Http://coliru.stacked-crooked.com/a/b9828b8eaf4d59e3) – Nelfeal

+0

Tôi không tin rằng tôi đã viết bất kỳ điều gì trái ngược. – Shiro

+0

@Nelxiost Bạn có nó ngược. 'std :: is_integral' chỉ ra nếu một kiểu là tích phân, được định nghĩa bởi tiêu chuẩn và việc thực hiện.Chuyên môn trong 'std ::' là (thường) UB – Caleth

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