Шаблонная специализация с зависимыми значениями

Использование шаблонов для размера массива кажется простым:

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];
};
Другие вопросы по тегам