Контейнеры STL требуют от хранимых объектов наличия конструктора копирования и оператора присваивания.
А я хочу хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно).
Мне кажется, что вполне возможно реализовать контейнеры, похожие на стандартные, но использующие конструктор по умолчанию и функцию swap (вместо конструктора копирования и оператора присваивания). И, наверное, я на днях попробую это сделать (начну с вектора).
Вот только меня терзают сомнения:
1) Может, уже существуют подобные контейнеры? (В Boost-е их вроде нет).
Или какие-нибудь адаптеры к стандартным контейнерам?
2) Может, эта идея изначально порочная и бессмысленная?
Re: Контейнеры для Swap-able объектов
От:
Аноним
Дата:
10.12.07 22:27
Оценка:
Здравствуйте, Atminav, Вы писали:
A>... A>А я хочу хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно). A>...
А что мешает хранить указатели на объекты и их swap-ать? Да и копируются указатели довольно эффективно
Здравствуйте, Аноним, Вы писали:
А>А что мешает хранить указатели на объекты и их swap-ать? Да и копируются указатели довольно эффективно
Нужно выделять память, не забывать освобождать ее, да еще следить, чтобы указатель не был 0... Кроме того, указатели — это лишний уровень косвенности, лишнии операции при обращении к объекту.
Вообще, не хочется без лишней необходимости пользоваться new/delete. Так что указатели, даже смарт-указатели, я не рассматриваю.
Конечно, любой контейнер тоже пользуется new/delete. Но контейнер, который хранит сами объекты, а не указатели на них, выделяет память только при создании, изменении размера и уничтожении контейнера, а при изменении элементов он к аллокатору, по идее, обращаться не должен.
Здравствуйте, Atminav, Вы писали:
A>Нужно выделять память, не забывать освобождать ее, да еще следить, чтобы указатель не был 0... Кроме того, указатели — это лишний уровень косвенности, лишнии операции при обращении к объекту.
По поводу косвенной адресации не так уж она и долго происходит
Что мешает использовать указатели !=0 и без выделения памяти?
A>Вообще, не хочется без лишней необходимости пользоваться new/delete. Так что указатели, даже смарт-указатели, я не рассматриваю.
не хочется н вызывай. Организуй выделения элементов страницами. На каждой странице по N элементов сразу выделяется.
Если хочется можеш им и конструкторы вызывать переопределив void* operator new(void* where,size_t size);
А в сбалансированном дереве хранить указатели или номера элементов и работать уже с ними. Указатель всего одно машинное слово по сравнению со структурой которая может занимать килобайты.
Здравствуйте, Atminav, Вы писали:
A>Контейнеры STL требуют от хранимых объектов наличия конструктора копирования и оператора присваивания. A>А я хочу хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно).
Так не могут, или неэффективно могут? Это две совершенно разные ситуации.
Если неэффективно могут:
1. Можно понадеяться, что для внутренних целей (например, при вставке/удалении/перемещении элементов вектора) STL использует всё-таки swap(), а не копирование.
2. Сделай операции вставки двухступенчатыми. Это всего лишь вопрос практики применения контейнеров.
vec.push_back(Value());
swap(vec.back(), v);
Если не могут:
Прямая дорога к указателям с разделяемым владением.
Здравствуйте, Atminav, Вы писали:
A>Контейнеры STL требуют от хранимых объектов наличия конструктора копирования и оператора присваивания.
A>А я хочу хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно).
A>Мне кажется, что вполне возможно реализовать контейнеры, похожие на стандартные, но использующие конструктор по умолчанию и функцию swap (вместо конструктора копирования и оператора присваивания). И, наверное, я на днях попробую это сделать (начну с вектора).
A>Вот только меня терзают сомнения: A>1) Может, уже существуют подобные контейнеры? (В Boost-е их вроде нет). A> Или какие-нибудь адаптеры к стандартным контейнерам?
A>2) Может, эта идея изначально порочная и бессмысленная?
Ну а потом реализуешь контейнер через вызовы такой функции...
В моей любимой библиотеке сделано примерно так, только там ещё много всяких хитростей на тему о том, как определять такого типа функции автоматически...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, _nn_, Вы писали:
A>>Контейнеры STL требуют от хранимых объектов наличия конструктора копирования и оператора присваивания.
A>>А я хочу хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно).
__>Boost.PtrContainers подойдет ?
Так он, вроде, требует клонируемости (практически то же, что и копируемость) объектов и клонирует их при вставке в контейнер.
Здравствуйте, Кодт, Вы писали:
A>>хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно).
К>Так не могут, или неэффективно могут? Это две совершенно разные ситуации.
Помоему, разница невелика. В одном случае, их НЕЛЬЗЯ копировать, а в другом — НЕЖЕЛАТЕЛЬНО.
К>Если неэффективно могут:
К>1. Можно понадеяться, что для внутренних целей (например, при вставке/удалении/перемещении элементов вектора) STL использует всё-таки swap(), а не копирование.
Сомнительно. Откуда STL знает, что эффективнее: swap или копирование? Основной шаблон swap использует три копирования и один деструктор, так что он в три раза менее эффективен, чем копирование. Однако, для некоторых объектов swap может быть на порядки эфективнее, чем копирование.
К>2. Сделай операции вставки двухступенчатыми. Это всего лишь вопрос практики применения контейнеров. К>
Здравствуйте, Atminav, Вы писали:
A>>>хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно).
К>>Так не могут, или неэффективно могут? Это две совершенно разные ситуации. A>Помоему, разница невелика. В одном случае, их НЕЛЬЗЯ копировать, а в другом — НЕЖЕЛАТЕЛЬНО.
Разница гигантская.
Если некий объект вовсю эксплуатирует свою идентичность, либо монопольно владеет ресурсами, то копирование запрещено.
А если это просто тяжеловесное значение (большая строка), то копировать или нет — лишь вопрос эффективности. Кстати, посмотри на идиому COW (copy on write).
К>>Если неэффективно могут:
К>>1. Можно понадеяться, что для внутренних целей (например, при вставке/удалении/перемещении элементов вектора) STL использует всё-таки swap(), а не копирование. A>Сомнительно. Откуда STL знает, что эффективнее: swap или копирование?
STL думает, что swap эффективнее.
A> Основной шаблон swap использует три копирования и один деструктор, так что он в три раза менее эффективен, чем копирование. A> Однако, для некоторых объектов swap может быть на порядки эфективнее, чем копирование.
И именно для этих объектов пишется специализация swap. Например, для всех контейнеров.
А если пользователь тормоз, и положился на основной шаблон (реализованный через копирования и присваивания) — его программа просто будет работать медленнее.
К>>2. Сделай операции вставки двухступенчатыми. Это всего лишь вопрос практики применения контейнеров. К>>
Здравствуйте, Atminav, Вы писали:
A>Здравствуйте, _nn_, Вы писали:
A>>>Контейнеры STL требуют от хранимых объектов наличия конструктора копирования и оператора присваивания.
A>>>А я хочу хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно).
__>>Boost.PtrContainers подойдет ?
A>Так он, вроде, требует клонируемости (практически то же, что и копируемость) объектов и клонирует их при вставке в контейнер.
Здравствуйте, Atminav, Вы писали:
A>А я хочу хранить объекты, которые имеют простые и быстрые конструктор по умолчанию и функцию swap, но не могут копироваться (или могут, но неэффективно).
A> Или какие-нибудь адаптеры к стандартным контейнерам?
Мне кажется правильное направление — не так сложно создать swapable адаптер для объектов. Но, думается что лучше использовать некоторую связку:
адаптер + надстройка над стандартными контейнерами с ограниченными возможностями (что-бы можно было следить за операциями, когда требуется действительно копирование, а не swap).
Ещё следует не забывать о том, что с контейнерами могут работать различные алгоритмы, которые могут подразумевать, что переданные итераторы указывают на copy-constructable данные.