Как вывести размер массива из аргумента шаблона enum? - PullRequest
8 голосов
/ 15 февраля 2011

Как мне изменить приведенный ниже код так, чтобы Array<Index> array; было достаточно, а SIZE автоматически выводилось из перечисления?Даже если перечисление изменяется, гарантируется, что оно содержит SIZE, ссылаясь на правильный размер.

template <typename Enum, int N>
class Array {

public:
    int& operator[](Enum index) { return array[index]; }

private:
    int array[N];
};

enum Index { X, Y, SIZE };

int main() {

    Array<Index, SIZE> array;

    array[X] = 1;

    return 0;
}

ОБНОВЛЕНИЕ: Что касается "Массив " означает, что вы создаетемассив объектов Type »(Джерри) и« имя шаблона класса немного вводит в заблуждение »(Наваз): на самом деле я создаю CustomSqlQueryModel .Выше просто упрощенный код, не более того.Джерри и Наваз правы: этот упрощенный код неудачен.

Ответы [ 3 ]

6 голосов
/ 15 февраля 2011

Вы можете написать класс черт. Это требует немного дополнительной работы каждый раз, когда вы определяете новый тип перечисления, но не требует дополнительной работы для каждого вхождения массива в коде пользователя:

template<class Enum>
struct ArrayTraits;

template<class Enum>
struct Array {
  int& operator[](Enum index) { return array[index]; }

private:
  int array[ArrayTraits<Enum>::size];
};

enum Index { X, Y, SIZE };

template<>
struct ArrayTraits<Index> {
  enum { size = SIZE };
};


int main() {
  Array<Index> array;
  array[X] = 1;
  return 0;
}

Одним из преимуществ этого является то, что вы можете специализировать черты для внешних перечислений, которые вы не контролируете, если вы знаете, как получить максимальный размер.

1 голос
/ 15 февраля 2011

Как уже говорилось, я не думаю, что вы можете.Однако, если вы измените его на что-то вроде:

struct Index { 
    enum { X, Y, SIZE};
};

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

template <class Enum>
class Array { 
// ...

private:
    int array[Enum::SIZE];
};

... и если тип вы передаете как Enumне содержит некоторой положительной константы с именем SIZE, инстанцирование не будет компилироваться.Для данной цели вы бы предпочли, чтобы Index было пространством имен, но поскольку пространство имен не является типом, я не думаю, что вы можете использовать его в качестве аргумента шаблона.

Я должен добавить, однако, что я не уверен, что мне вообще нравится эта идея - большинство людей будут думать, что Array<type> означает, что вы создаете массив Type объектов, и это явно что-то совершенно другоеиз этого ...

0 голосов
/ 15 февраля 2011

Если вы хотите, чтобы аргумент шаблона был только size , а не type , как из вашего примера кажется, что type массива будет всегда int, тогда почему бы вам не реализовать это:

template <int size>
class Array {

public:
    int& operator[](int index) { return array[index]; }

    //Note this addition!
    int operator[](int index) const { return array[index]; }
private:
    int array[size];
};

int main() {

    Array<10> array;

    array[0] = 1;
    array[1] = 2;

    return 0;
}

Обратите внимание на это дополнение: лучше, если вы также реализуете константную версию operator[], чтобы const Array<> мог использовать ее для доступа к элементам массива, иначе ваш класс не будет работать для const Array<>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...