LINUX.ORG.RU

vector vs unique_ptr

 


0

2

Есть много API функций вида getData(void *pvData), которые заполняют буфер (часто - большого размера)
Заполнять этот буфер перед вызовом нет смысла.
По дальнейшему использованию удобнее vector, но он при создании будет инициализировать элементы. Есть способ этого избежать?


он при создании будет инициализировать элементы

если писать std::vector<T> v(10); то конечно будет. иначе - не будет.

x0r ★★★★★
()

С помощью unique_ptr удобно передавать право владения объектом, получается самодокументируемый код. Не совсем понял при чем он в твоем вопросе. Касательно вектора, создавай пустой, а потом вызывай reserve.
EDIT: Хотя я не ответил на твой вопрос, после вызова reserve capacity вектора станет подходящего размера и в его память даже можно записать данные, но вот сам вектор об этом будет не в курсе.

m0rph ★★★★★
()
Последнее исправление: m0rph (всего исправлений: 1)

но он при создании будет инициализировать элементы

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

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

unique_ptr он копировать точно не будет.

anonymous
()
Ответ на: комментарий от m0rph

но вот сам вектор об этом будет не в курсе

В том то и дело.

Имеется в виду специализация unique_ptr<T[]>

Или в зависимости от конкретной реализации изменять значение указателя на конец данных?

Uter
() автор топика
Последнее исправление: Uter (всего исправлений: 1)
Ответ на: комментарий от no-such-file

копировать элементы

Да, ты прав - я забыл этот момент.

Всё равно ненужный оверхед, если нужен «умный» буфер на N мегабайт

Uter
() автор топика
Ответ на: комментарий от Uter

unique_ptr ничего не знает о размере куска памяти, придётся таскать с собой дополнительный параметр или писать небольшую обёртку

Gvidon ★★★★
()

getData(char *pvData, size_t datasize),

fxd.

Если надо массив, то я всегда использую unique_ptr в таких случаях. Если просто указатель на структуру например то shared_ptr.

Вектор имеет смысл использовать, если ты потом будешь что-либо из <algorithm> примерять. foreach например. Или find/sort.

nanoolinux ★★★★
()
Последнее исправление: nanoolinux (всего исправлений: 1)

vector vs unique_ptr

Только сейчас допёр, в чем вопрос. Понятнее надо выражать свои мысли, товарищ программист.

По дальнейшему использованию удобнее vector

Т.е. что, надо будет добавлять элементы что-ли?

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Он будет копировать только тогда, когда ты ему скажешь.

anonymous
()
Ответ на: комментарий от Gvidon

Как будто в спп нельзя сделать ьталедс или что-то в этом духе.

nanoolinux ★★★★
()
Ответ на: комментарий от Uter

Итераторы

Чем обычные указатели не угодили?

не надо размер отдельно таскать

Простенькая структурка, состоящая из указателя и size_t поля, пишется минут за 5, ты гораздо больше времени тут потратил

Gvidon ★★★★
()
Ответ на: комментарий от crowbar
std::vector<uint8_t> buff(100500);
getData(buff.data());

Удобнее, но конструктор будет занулять 100500 байт

auto buff = std::make_unique<uint8_t[]>(100500);
getData(buff.get());

Нет лишнего зануления, но чуть менее удобно в дальнейшем

Uter
() автор топика
Ответ на: комментарий от Gvidon

пишется минут за 5

ну тогда уж за 15 минут копипастится std::vector и переделывается в какой-нибудь mystd::heap_array

Uter
() автор топика
Ответ на: комментарий от Uter

Куда таскать размер? Указатели вполне работают как итераторы(собственно, итераторы - это обобщение указателей), так что все стандартные алгоритмы будут доступны.

anonymous
()
Ответ на: комментарий от crowbar

неизвестно сколько мегабайт размещать в стеке?

Uter
() автор топика
Ответ на: комментарий от anonymous

ну, либо указатель на конец данных для unique_ptr илибо размер

Uter
() автор топика

По дальнейшему использованию удобнее vector, но он при создании будет инициализировать элементы. Есть способ этого избежать?

напиши свой вектор СБИШ

emulek
()
Ответ на: комментарий от one_more_hokum

Размер задаётся на этапе компиляции, память выделяется на стеке. std::array вряд ли годится на роль общего решения

Gvidon ★★★★
()
Ответ на: комментарий от AlexVR

Как unique_ptr связан с многопоточность?

anonymous
()
Ответ на: комментарий от Gvidon

std::array вряд ли годится на роль общего решения

No silver bullet, я знаю. Для определённых применений он очень даже OK.

one_more_hokum ★★★
()

Не надо экономить на спичках. Если нужен буфер, используй std::vector<char>. Пускай инициализируется.

Такой код должен быть понятен всем.

Если бы API можно было изменить и если бы заполняемый буфер представлял собой линейных массив объектов одного типа, то проще было бы использовать функцию std::vector<T>::emplace_back() внутри функции getData() и передавать в функцию vector<T>, а не void*.

pathfinder ★★★★
()
Последнее исправление: pathfinder (всего исправлений: 2)

А ещё лучше определиться со стилем кода. Активное использование void*, это не то, что хорошо вяжется с идеологией активного использования контейнеров STL и прочих возможностей современного с++.

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

не то, что хорошо вяжется с идеологией активного использования контейнеров STL и прочих возможностей современного с++.

Но вполне в духе сишныйх API

Uter
() автор топика
Ответ на: комментарий от Uter

Но вполне в духе сишныйх API

Ну тогда работай в слое взаимодействия с этим API в сишном стиле. Большие ценители «pure C» не имеют дела с STL и таких вопросов не задают.

pathfinder ★★★★
()
Ответ на: комментарий от AlexVR

А потом другим добиться с потоко-безопасностью.

Чё? У меня сегфолт в парсере от этого предложения.

nanoolinux ★★★★
()
Ответ на: комментарий от no-such-file

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

Reference? std::move?

Deleted
()
5 сентября 2014 г.

Не уверен, но может так не будет делаться инициализация:

std::vector<int> v;
v.resize(count);

andreyu ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.