2012-01-31 3 views
12

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

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

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

ответ

15

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

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

+3

Я бы сказал, используя std :: vector над unique_ptr , первый совместим со всеми стандартными библиотечными функциями, которые работают на итераторах. Фактически вся точка std :: array должна обеспечивать такой интерфейс над обычным массивом. –

+3

@ user1131467: Действительно, 'std :: vector' намного удобнее; но ОП действительно выразил озабоченность по поводу эффективности, поэтому, возможно, сохранение нескольких байтов важно. –

+0

Если вы собираетесь писать обертку в стиле STL, то по крайней мере она также должна знать ее размер. Вы можете только не беспокоиться о емкости. – UncleBens

6

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

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

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

+0

IIRC, вектор сконструирован с * точно * способностью, о которой вы просите. После этого не нужно сокращаться.С этим и опирается трюк «копирование и своп» для сжатия вектора. – Xeo

+1

Интересно, что для некоторых тестов нет никаких накладных расходов, а 'std :: vector'-code дает тот же векторный код SSE, что и для собственных массивов (по крайней мере, с g ++) –

+0

Я думаю, что массив выделен на месте и вектор распределяется динамически. –

11

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

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

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

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

+1

или вместо 'resize()', используйте конструктор 'std :: vector (size_t n)'. –

+2

@phresnel: или 'reserve' + последовательность' push_back'/'emplace_back', если не все ваши элементы должны быть одинаковыми. –

3

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

Смежные вопросы