Is there a way to initialize a container (e.g. std::unordered_set<char>) with the enumerators of an enum class?
I have this class:
#include <iostream>
#include <unordered_set>
class Foo
{
public:
inline static const std::unordered_set<char> chars_for_drawing { '/', '\\', '|', '-' };
};
int main( )
{
for ( const char ch : Foo::chars_for_drawing )
{
std::cout << ch << ' ';
}
}
But I want the chars_for_drawing set to be initialized with the enumerators:
#include <iostream>
#include <unordered_set>
class Foo
{
public:
enum class AllowedChars : char
{
ForwardSlash = '/',
BackSlash = '\\',
VerticalSlash = '|',
Dash = '-'
};
// inline static const std::unordered_set<char> chars_for_drawing { '/', '\\', '|', '-' }; // not like this
inline static const std::unordered_set<char> chars_for_drawing {
static_cast<char>( AllowedChars::ForwardSlash ),
static_cast<char>( AllowedChars::BackSlash ),
static_cast<char>( AllowedChars::VerticalSlash ),
static_cast<char>( AllowedChars::Dash )
};
};
int main( )
{
for ( const char ch : Foo::chars_for_drawing )
{
std::cout << ch << ' ';
}
}
As can be seen, the second approach is a bit messy. Is there way to iterate over the enumerators and assign them to the unordered_set? Maybe by using a lambda?
No there is no straightforward way. Something one often forgets: The range of the enums values is determined by its underlying type. The enumerators are just some named constants. Your enum:
helps for iterating as much as a
does: Not at all.
Things are different when the enumerators have consecutive values and a hack that is used sometimes is to use a special enumerator to denote the "size":
That alone is a little silly, because the mapping to the actual characters is lost. However, it can be supplied by an array:
TL;DR Reconsider if an enum is the right tool for the job. Enums are often overestimated for what they can really do. Sometimes not an enum is the better alternative.