Шаблонная специализация с зависимыми значениями
Использование шаблонов для размера массива кажется простым:
template <size_t N>
struct MyArray
{
char array[N];
};
Однако я хотел бы установить размер массива на основе чего-то еще:
enum MyEnum {Hi, Lo};
template <MyEnum T, size_t N>
struct MyArray
{
MyEnum type() { return T; }
char array[N];
};
Как мне установить N на 10, когда MyEnum - Hi, и на 200, когда MyEnum - Lo?
Что я хотел бы сделать, это сказать
MyArray<Lo> lo; // Result in MyArray<Lo, 200>
MyArray<Hi> hi; // Result in MyArray<Hi, 10>
вместо того, чтобы сказать
MyArray<Lo, 200> lo;
MyArray<Hi, 10> hi;
Это возможно?
2 ответа
Решение
Вы можете сделать значение по умолчанию для N
сразу же, как вы сделали бы с обычными параметрами функции:
enum MyEnum { Hi, Lo };
template <MyEnum T, size_t N = (T == Hi ? 10 : 200)> // parentheses for clarity
struct MyArray { ... };
У вас есть несколько возможностей
Используйте вычисление N
прямо в основной класс:
template <MyEnum E>
class MyArray
{
constexpr std::size_t N = (E == Hi ? 10 : 200);
public:
MyEnum type() { return E; }
char array[N];
};
или специализироваться
template <MyEnum E> struct MyArraySize;
template <> struct MyArraySize<Hi> : std::integral_constant<std::size_t, 10> {};
template <> struct MyArraySize<Low> : std::integral_constant<std::size_t, 200>{};
template <MyEnum E>
class MyArray
{
public:
MyEnum type() { return E; }
char array[MyArraySize<E>::value];
};