Reputation: 503
My goal is to create an alias for a std::array
that sets the length based on an enum template argument. I managed to make it work relying on the conversion of the enum, as seen in my code below.
#include <array>
#include <iostream>
enum class StateRepresentation
{
Log2 = 1,
One_hot = 16
};
template <StateRepresentation R>
using State = std::array<int, static_cast<int>(R) * 16>;
int main(void)
{
const auto curr_repr = StateRepresentation::One_hot;
auto b = State<curr_repr>{};
std::cout << "Representation value: " << static_cast<int>(curr_repr) << '\n';
std::cout << "Array length: " << b.size() << '\n';
return 0;
}
Would it be possible to achieve the same but without relying on static_cast
to obtain the numeric value of the enumerator?
I attempted something along the lines of template specialization as seen below, but failed to make it work:
template <>
using State<StateRepresentation::Log2> = std::array<int, 1 * 16>;
template <>
using State<StateRepresentation::One_hot> = std::array<int, 16 * 16>;
Upvotes: 1
Views: 36
Reputation: 60228
You can use conditional_t
to switch on which member of the enum class is used for instantiation:
template <StateRepresentation R>
using State = std::conditional_t<R == StateRepresentation::Log2,
std::array<int, 1 * 16>,
std::array<int, 16 * 16>>;
This avoids the need for the enum class members to have the same values as the ones you want to use in the std::array
.
As pointed out in a comment, you could also use a ternary condition in the array parameter itself to pick the size you want
template <StateRepresentation R>
using State = std::array<int, (R == StateRepresentation::Log2 ? 1 : 16) * 16>;
Upvotes: 1