C ++ 11 std :: array - PullRequest
       46

C ++ 11 std :: array

12 голосов
/ 31 января 2012

Я хотел бы использовать std::array из C ++ 11 в качестве поля моего собственного класса. Он принимает два параметра шаблона (первый определяет тип данных, второй определяет размер массива).

Но я знаю второй параметр только в конструкторе. Я не знаком со стандартом C ++ 11, но полагаю, что невозможно установить параметр шаблона во время выполнения.

Есть ли альтернативы для std::array? std::vector, вероятно, немного слишком много, потому что я никогда не изменю его размер.

Ответы [ 4 ]

15 голосов
/ 31 января 2012

std::vector - самая простая вещь для использования; хотя, как вы говорите, он теряет несколько байтов, если вам никогда не потребуется изменять его размер.

std::unique_ptr<T[]>, инициализированный с использованием результата new T[size], будет самой эффективной вещью; он должен быть того же размера, что и указатель, и удалит выделенную память для вас, когда он будет уничтожен. Это не копируется, хотя; вам нужно будет предоставить конструктор копирования для вашего класса, если вы хотите, чтобы он был копируемым. Это также менее удобно, чем std::array и std::vector, поскольку не имеет интерфейса стандартного контейнера. Вы можете написать обертку в стиле STL, если вам это нужно; но я бы просто использовал std::vector в этом случае.

11 голосов
/ 31 января 2012

Я не знаком со стандартом C ++ 11, но полагаю, что невозможно установить параметр шаблона во время выполнения.

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

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

Если честно, в вашей ситуации, скорее всего, std::vector будет лучшим решением, поскольку вы можете просто вызвать resize() для вектора, чтобы сделать его правильным во время выполнения посредством динамического выделения.

6 голосов
/ 31 января 2012

std :: array предназначен для статического определения размера во время компиляции.Если вы не знаете до времени выполнения, используйте std :: vector.Если вы не измените его размер, то там не будет много накладных расходов.

class Container
{
    vector<T> v;
    Container(int i) : v(i) { v.shrink_to_fit(); }
};

Если вас беспокоит пространство:

http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit

Не уверен, что естьспособ построения вектора уже обрезан.Похоже, что стандарт не требует триммирования, хотя на практике многие реализации будут делать это.

Кстати, вы также можете построить вектор с вектором (size_t N, T t), который установиткаждый начальный элемент в t (без этого элементы создаются по умолчанию).

3 голосов
/ 31 января 2012

Если вы не знаете размер массива до времени выполнения, тогда вы хотите использовать std :: vector.

...