2016-11-27 20 views
9

Có cách nào để chọn ngẫu nhiên một phần tử từ một kiểu liệt kê theo cách an toàn không? Cách tốt nhất để làm điều đó, mà tôi có thể tìm thấy, là giới thiệu một giá trị terminator như phần tử cuối cùng của enum, vì vậy bạn biết có bao nhiêu giá trị, sau đó tạo một số nguyên ngẫu nhiên trong phạm vi thích hợp mà bạn cast vào enum. Nhưng một giá trị terminator không đại diện cho bất cứ điều gì, vì vậy sau đó bạn có một giá trị enum không hợp lệ, và điều này không phải là loại an toàn. Có cách nào tốt hơn để làm điều đó trong các tiêu chuẩn C++ mới nhất?Chọn ngẫu nhiên một phần tử từ một kiểu liệt kê theo cách an toàn kiểu mới nhất với C++

+1

Thú vị, nhưng tất cả nắm xuống "là có một, kiểu an cách phổ biến để xác định có bao nhiêu giá trị trong một enum?" và câu trả lời cho điều đó thật đáng buồn là không. Thành ngữ tiêu chuẩn là, như bạn đề cập, để bao gồm một giá trị sentinel trong enum, nhưng tôi đồng ý rằng là xấu xí. Giải pháp khác duy nhất của bạn thực sự sẽ là viết một lớp tùy chỉnh để đại diện cho enum của bạn, cung cấp một số loại chuyển đổi tiềm ẩn, nhưng điều đó gần như chắc chắn được thiết kế quá mức. Bên cạnh đó, nó trở nên tồi tệ hơn lần đầu tiên có vẻ như: các giá trị trong một enum không phải tăng tuyến tính; có thể nhảy và gián đoạn. –

Trả lời

3

Điều này có vẻ giống như một trường hợp sử dụng tốt cho một câu hỏi std::map

std::map<std::string, const int> nicer_enum {{"Do", 3}, {"Re", 6}, {"Mi", 9}}; 

std::cout << nicer_enum["Re"] << '\n'; // 6 

auto elem = nicer_enum.cbegin(); 
std::srand(std::time(nullptr)); 
std::advance(elem, std::rand() % nicer_enum.size()); 
std::cout << elem->second << '\n'; // 3, 6 or 9 

for (const auto &kv : nicer_enum) 
     std::cout << kv.first << ": " << kv.second << ' '; // Do: 3 Mi: 9 Re: 6 

std::cout << '\n'; 
+0

Tuyệt vời! Nhưng sẽ tốt hơn nếu bạn sử dụng '' và 'std :: string' thay vì các kỹ thuật trước C++ 11. – Rakete1111

+0

Đồng ý, nhưng tôi không muốn phân tâm từ phần liên quan của câu trả lời của tôi. (Và bạn có lẽ không nên thay đổi kích thước các phím bản đồ dù sao đi nữa). –

+0

@RayHamel: Việc sử dụng 'const char *' * làm * phân tâm khỏi phần liên quan của câu trả lời của bạn. –

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