Simple question, how to initialize a map of arrays (or some other container type) of different sizes? For example:
enum class code {A,B,C};
enum class res {X1,X2,X3,X4,X5};
std::map<code, ?> name {
{code:A, {res::X1,res::X2}},
{code:B, {res::X2,res::X3, res::X4}},
{code:C, {res::X5}}
};
I need to find at compile time if res::X2
is in map name
at code::B
This expression should, I think, check for that using static_assert
:
constexpr bool validate(code t, res p, int i = 0) {
return (name[t][i] == p ? true : ((sizeof(name[t]) == (i+1)) ? false :validate(t, p, ++i)));
}
Because validate
is a constexpr
a basic array would work but how to define it in a map argument as an array of type res
? And that each array could be different in size?
So, I've made a mistake. I was under the impression that map can be accessed in constexpr function. What container type can you suggest me that would allow me to achieve what I have written above?
Since std::map
can't be used in constexpr
expression I was forced to find another solution and thanks to @kfsone and @H. Guijt for pointing that out as well as mentioning std::initializer_list
and std::array
which lead me to this solution.
Since the data in the map in the question will be constant, i can do without an associative container. So I used a sorted array of std::initializer_list
s together with a constexpr
implementation of find function which works great for my needs.
template <class It, class T>
inline constexpr It sfind (It begin, It end, T const& value) noexcept
{
return ! (begin != end && *begin != value)? begin : sfind (begin+1, end, value);
}
enum class code {A,B,C};
enum class res {X1,X2,X3,X4,X5};
constexpr std::array<std::initializer_list<res>, 3> name {{
{res::X1,res::X2}, //code::A
{res::X2,res::X3, res::X4}, //code::B
{res::X5} // code::C
}};
const code c = code::A;
const res r = res::X3;
static_assert (name[static_cast<int>(c)].end () - sfind(name[static_cast<int>(c)].begin(), name[static_cast<int>(c)].end(), r) != 0,"Not found");