Вход/Регистрация
Эффективное использование STL
вернуться

Мейерс Скотт

Шрифт:

size_t fillArray(double *pArray, size_t arraySize);

vector<double> vd(maxNumDoubles); // Создать vector, емкость которого

// равна maxNumDoubles

vd.resize(fillArray(&vd[0], vd.size)); // Заполнить vd вызовом

// функции fillArray, после чего

// изменить размер по количеству

// записанных элементов

Данный способ подходит только для

vector
, поскольку только этот контейнер заведомо совместим с массивами по структуре памяти. Впрочем, задача инициализации
string
функцией C тоже решается достаточно просто. Данные, возвращаемые функцией, заносятся в
vector<char>
и затем копируются из вектора в
string
:

// Функция получает указатель на массив, содержащий не более

// arraySize символов, и записывает в него данные.

// Возвращаемое количество записанных чисел заведомо не превышает

// maxNumChars

size_t fillString(char *pArray, sizet arraySize);

vector<char> vc(maxNumChars); // Создать vector, емкость которого

// равна maxNumChars

size_t charsWritten = fillString(&vc[0],vc.size); // Заполнить vc

// вызовом fillString

string s(vc.begin, vc.begin+charsWritten); // Скопировать данные

// из vc в s интервальным

// конструктором (совет 5)

Собственно, сам принцип сохранения данных функцией API в

vector
и их последующего копирования в нужный контейнер STL работает всегда:

size_t fillArray(double *pArray, size_t arraySize); // См. ранее

vector<double> vd(maxNumDoubles);// Также см. ранее

vd.resize(fillArray(&vd[0], vd.size);

deque<double> d(vd.begin, vd.end); // Копирование в deque

list<double> l(vd.begin, vd.end); // Копирование в list

set<double> s(vd.begin, vd.end); // Копирование в set

Более того, этот фрагмент подсказывает, как организовать передачу данных из других контейнеров STL, кроме

vector
и
string
, функциям C. Для этого достаточно скопировать данные контейнера в
vector
и передать его при вызове:

void doSomething(const int* pints, size_t numInts); // Функция C (см. ранее)

set<int> intSet; // Множество, в котором

… // хранятся передаваемые

// данные

vector<int> v(intSet.begin, intSet.end);// Скопировать данные

// из set в vector

if (!v.empty) doSomething(&v[0], v.size); // Передать данные

// функции С

Вообще говоря, данные также можно скопировать в массив и передать их функции C, но зачем это нужно? Если размер контейнера не известен на стадии компиляции, память придется выделять динамически, а в совете 13 объясняется, почему вместо динамических массивов следует использовать

vector
.

Совет 17. Используйте «фокус с перестановкой» для уменьшения емкости

Предположим, вы пишете программу для нового телешоу «Бешеные деньги». Информация о потенциальных участниках хранится в векторе:

class Contestant {…};

vector<Contestant> contestants;

При объявлении набора участников заявки сыплются градом, и вектор быстро заполняется элементами. Но по мере отбора перспективных кандидатов относительно небольшое количество элементов перемещается в начало вектора (вероятно, вызовом

partial_sort
или
partition
— см. совет 31), а неудачники удаляются из вектора (как правило, при помощи интервальной формы
erase
— см. совет 5). В результате удаления длина вектора уменьшается, но емкость остается прежней. Если в какой-то момент времени вектор содержал данные о 100 000 кандидатов, то его емкость останется равной 100 000, даже если позднее количество элементов уменьшится до 10.

  • Читать дальше
  • 1
  • ...
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: