2016-11-27 9 views
9

タイプセーフな方法で列挙から要素をランダムに選択する方法はありますか?最新のC++でタイプセーフな方法で列挙から要素をランダムに選択

私が見つけることができる最もよい方法は、列挙子の最後の要素としてターミネーター値を導入することです。その結果、いくつの値があるか分かり、適切な範囲でランダムな整数を生成します列挙型にキャストしかし、ターミネーター値は何も表していないので、無効なenum値があります。これは型セーフではありません。最新のC++標準でそれを行うより良い方法はありますか?

+1

興味深い質問のために良いユースケースのように思えるが、それはすべてに沸く「多くの値が列挙型であるかを決定するための普遍的な、型安全な方法はありますか?」それに対する答えは、悲しいことに、いいえです。あなたが言及しているように、標準イディオムは列挙型の値を列挙型に含めることですが、私はそれが醜いことに同意します。あなたの唯一の他の解決策は、何らかの種類の暗黙的な変換を提供するカスタムクラスを記述してenumを表現す​​ることですが、それはほぼ確実に過剰に設計されています。それに、列挙型の値が直線的に増加する必要はありません。ジャンプや不連続が生じる可能性があります。 –

答えて

3

これは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

ニース!しかし、pre-C++ 11のテクニックの代わりに ''と 'std :: string'を使った方が良いでしょう。 – Rakete1111

+0

合意しましたが、私は私の答えの関連部分から気をそらさないようにしたくありませんでした。 (マップキーのサイズを変更しないでください)。 –

+0

@RayHamel: 'const char *' *を使用すると、答えの関連部分が気になることがあります。 –

関連する問題