2016-11-27 1 views
9

auswählen Gibt es eine Möglichkeit, ein Element aus einer Aufzählung in einer typsicheren Weise zufällig auszuwählen?Nach dem Zufallsprinzip ein Element aus einer Enumeration in einer typsicheren Weise mit dem neuesten C++

Der beste Weg, es zu finden, ist, einen Terminatorwert als letztes Element der Enumeration einzuführen, damit Sie wissen, wie viele Werte es gibt, und dann eine zufällige Ganzzahl in dem entsprechenden Bereich erzeugen in die Enum werfen. Aber ein Terminator-Wert repräsentiert nichts, also haben Sie einen ungültigen Enum-Wert, und das ist nicht typsicher. Gibt es einen besseren Weg, es in den neuesten C++ - Standards zu tun?

+1

Interessante Frage, aber es läuft alles auf „ist es eine universelle, typsichere Art und Weise, wie viele Werte der Bestimmung in einer Enum sind?“ und die Antwort darauf ist leider nein. Das Standard-Idiom ist, wie Sie erwähnen, einen Sentinel-Wert in der Enum, aber ich stimme zu, dass es hässlich ist. Ihre einzige andere Lösung wäre es, eine benutzerdefinierte Klasse zu schreiben, die Ihr enum darstellt und eine Art implizite Konvertierung bietet, aber das ist mit ziemlicher Sicherheit überentwickelt. Außerdem wird es schlimmer als es zunächst scheint: Die Werte in einem Enum müssen nicht linear ansteigen; es kann Sprünge und Diskontinuitäten geben. –

Antwort

3

Dies scheint ein guter Anwendungsfall für eine 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

Schön! Aber es wäre besser, wenn Sie '' und 'std :: string' anstelle von Techniken vor C++ 11 verwenden würden. – Rakete1111

+0

Einverstanden, aber ich wollte nicht von dem relevanten Teil meiner Antwort ablenken. (Und Sie sollten wahrscheinlich nicht die Größe von Kartenschlüsseln ändern). –

+0

@RayHamel: Die Verwendung von 'const char *' * lenkt * von dem relevanten Teil Ihrer Antwort ab. –

Verwandte Themen