Вот что нынче рекомендуют делать с такими объектами, если надо их массово хранить?
Если положить в STL контейнер, то UB?
Хранить указатели на них как-то не хочется — заранее известно, что их будет много, поэтому лучше сразу хапнуть побольше памяти.
Например, меня бы устроила std::deque или даже std::vector без возможности вставки в середину, релокации памяти вектора и т.п.
И никто не собирается понизить требования к объектам в STL?
А зачем им вообще понадобилось assignable? Чтобы двигать их по памяти, думаю, достаточно copy constructable.
Здравствуйте, <Аноним>, Вы писали:
А>Хранить указатели на них как-то не хочется — заранее известно, что их будет много, поэтому лучше сразу хапнуть побольше памяти.
Свою кучу ?
Small Object Allocator (если объекты маленькие)
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: Not copy constructable & assignable
От:
Аноним
Дата:
07.12.05 09:06
Оценка:
S>Свою кучу ? S>Small Object Allocator (если объекты маленькие)
Так ведь лень
Так можно и свою STL написать.
Да и не то, чтобы нужна была именно куча, просто большая группа одних объектов живёт вместе с другим.
Ситуация даже позволяет использовать new[], но
1) нет smart pointer'а которым это потом можно уничтожить
2) создаются они постепенно, и хотелось бы, чтобы кто-нибудь считал, сколько я уже насоздавал и где размещать следующий.
Здравствуйте, Аноним, Вы писали:
А>Вот что нынче рекомендуют делать с такими объектами, если надо их массово хранить? А>Если положить в STL контейнер, то UB?
Ну а что же еще, если тип не удовлетворяет поставленным требованиям?
А>Хранить указатели на них как-то не хочется — заранее известно, что их будет много, поэтому лучше сразу хапнуть побольше памяти. А>Например, меня бы устроила std::deque или даже std::vector без возможности вставки в середину, релокации памяти вектора и т.п.
В что насчет переопределения operator new/delete для этих типов?
А>И никто не собирается понизить требования к объектам в STL? А>А зачем им вообще понадобилось assignable? Чтобы двигать их по памяти, думаю, достаточно copy constructable.
Здравствуйте, Аноним, Вы писали:
А>Вот что нынче рекомендуют делать с такими объектами, если надо их массово хранить?
А если сделать CopyConstructible обёртку
template<class T> // DefaultConstructible, Assignableclass copiable
{
T value_;
public:
copiable() {}
copiable(T const& src) { value_ = src; }
copiable(copiable const& src) { value_ = src.value_; }
copiable& operator=(T const& src) { value_ = src; } // нужен, чтобы избежать промежуточного конструирования
copiable& operator=(copiable const& src) { value_ = src.value_; } // неявный оператор делает то же самое
// всякие там функции доступа...
T& get() { return value_; }
T const& get() const { return value_; }
operator T&() { return value_; }
operator T const&() const { return value_; }
};
Перекуём баги на фичи!
Re[2]: Not copy constructable & assignable
От:
Аноним
Дата:
07.12.05 09:24
Оценка:
А>>Вот что нынче рекомендуют делать с такими объектами, если надо их массово хранить? А>>Если положить в STL контейнер, то UB?
B>Ну а что же еще, если тип не удовлетворяет поставленным требованиям?
Ну, взяли бы и смягчили требования.
А>>Хранить указатели на них как-то не хочется — заранее известно, что их будет много, поэтому лучше сразу хапнуть побольше памяти. А>>Например, меня бы устроила std::deque или даже std::vector без возможности вставки в середину, релокации памяти вектора и т.п.
B>В что насчет переопределения operator new/delete для этих типов?
Хотелось бы чего-нибудь стандартного.
Не, ну правда, ведь присваивание и копирование для многих объектов не имеет смысла. Неужели это такой редкий случай?
А>>И никто не собирается понизить требования к объектам в STL? А>>А зачем им вообще понадобилось assignable? Чтобы двигать их по памяти, думаю, достаточно copy constructable.
B>Посмотри, например, на std::copy, std::remove.
Ну, в принципе да.
Но не всем же нужны эти std::copy, std::remove, а требования наложены глобально.
Здравствуйте, <Аноним>, Вы писали:
S>>Свою кучу ? S>>Small Object Allocator (если объекты маленькие)
А>Так ведь лень А>Так можно и свою STL написать. А>Да и не то, чтобы нужна была именно куча, просто большая группа одних объектов живёт вместе с другим. А>Ситуация даже позволяет использовать new[], но А>1) нет smart pointer'а которым это потом можно уничтожить А>2) создаются они постепенно, и хотелось бы, чтобы кто-нибудь считал, сколько я уже насоздавал и где размещать следующий.
В сторону boost::pool смотрели ?
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: Not copy constructable & assignable
От:
Аноним
Дата:
07.12.05 09:31
Оценка:
А>>Вот что нынче рекомендуют делать с такими объектами, если надо их массово хранить?
К>А если сделать CopyConstructible обёртку К>
К>template<class T> // DefaultConstructible, Assignable
К>class copiable
К>{
К> T value_;
К>public:
К> copiable() {}
К> copiable(T const& src) { value_ = src; }
К> copiable(copiable const& src) { value_ = src.value_; }
К> copiable& operator=(T const& src) { value_ = src; } // нужен, чтобы избежать промежуточного конструирования
К> copiable& operator=(copiable const& src) { value_ = src.value_; } // неявный оператор делает то же самое
К> // всякие там функции доступа...
К> T& get() { return value_; }
К> T const& get() const { return value_; }
К> operator T&() { return value_; }
К> operator T const&() const { return value_; }
К>};
К>
Насколько я вижу, она позволит обойтись без конструктора копирования, одним operator =(). Так?
Но он тоже не нужен.
Ну есть, например, окно (графическое).
Ну, зачем ему всё это? А хранить их в ящичке хочется.
Да я не за себя радею
Я то уже вывернулся (точнее, до меня вывернулись).
Просто интересно, комитет там ничего не собирается предпринять по этому поводу?
Re: Not copy constructable & assignable
От:
Аноним
Дата:
07.12.05 09:32
Оценка:
Даёшь "operator move" как единственное требование к помещаемым в контейнер объектам!
А без него пусть работают операции, не требующие передвигания объектов!
Здравствуйте, Аноним, Вы писали:
B>>Ну а что же еще, если тип не удовлетворяет поставленным требованиям? А>Ну, взяли бы и смягчили требования.
Поздно — слишком многое придется менять
B>>А что насчет переопределения operator new/delete для этих типов?
А>Хотелось бы чего-нибудь стандартного.
new/delete — куда еще стандартней? А>Не, ну правда, ведь присваивание и копирование для многих объектов не имеет смысла. Неужели это такой редкий случай?
Мое ИМХО — редкий. Да и наличие умолчательных конструктора копии и оператора присваивания в языке говорит о том, что такого же мнения придерживается и комитет
B>>Посмотри, например, на std::copy, std::remove.
А>Ну, в принципе да. А>Но не всем же нужны эти std::copy, std::remove, а требования наложены глобально.
Эти алгоритмы могут использоваться внутри сомой реализации библиотеки во множестве мест.
Встречный вопрос: Предложи реализацию вектора, например, в которой от элементов не требовалось бы свойсв copyconstructable & assignable
Здравствуйте, Bell, Вы писали:
B>Встречный вопрос: Предложи реализацию вектора, например, в которой от элементов не требовалось бы свойсв copyconstructable & assignable
Можете меня забить как мамонта, но я лично не согласен с унификацией требований copy constructable & assignable.
Я понимаю к какому хаосу привел бы отдельный набор требований для каждого контейнера, и каждой операции каждого контейнера, но иногда, я готов нырнуть в этот хаос, но не имею возможности
Здравствуйте, <Аноним>, Вы писали:
А>Вот что нынче рекомендуют делать с такими объектами, если надо их массово хранить? А>Если положить в STL контейнер, то UB?
А>Хранить указатели на них как-то не хочется — заранее известно, что их будет много, поэтому лучше сразу хапнуть побольше памяти. А>Например, меня бы устроила std::deque или даже std::vector без возможности вставки в середину, релокации памяти вектора и т.п.
А>И никто не собирается понизить требования к объектам в STL? А>А зачем им вообще понадобилось assignable? Чтобы двигать их по памяти, думаю, достаточно copy constructable.
Можно даже не доходить до вопросов реализации, а задуматься об интерфейсе.
С вектором можно делать, например так:
v.push_back(value); // что делаем здесь без конструктора копии?
v[idx] = value; // а здесь - без оператора присваивания?
*iter = value;
T value = *iter;
Чтобы быть совместимыми с интерфейсом контейнера, элементы контейнера должны быть assignable & copy constructible. Точка.
Если тип не удовлетворяет требованиям, в контейнер можно положить указатель или объект с аналогичной семантикой (его копирование не вызывает копирования указываемого объекта). Отсюда альтернативы: vector/list< shared_ptr<T> > (если объектов много, тяжелое решение), boost::pointer_container, vector<T*> и ручное управление временем жизни. А ускорение создания/удаления таких объектов — вопрос ортогональный и легко реализуется (особенно в однопоточном приложении).
Здравствуйте, Глеб Алексеев, Вы писали:
ГА>Здравствуйте, <Аноним>, Вы писали:
А>>Вот что нынче рекомендуют делать с такими объектами, если надо их массово хранить? А>>Если положить в STL контейнер, то UB?
А>>Хранить указатели на них как-то не хочется — заранее известно, что их будет много, поэтому лучше сразу хапнуть побольше памяти. А>>Например, меня бы устроила std::deque или даже std::vector без возможности вставки в середину, релокации памяти вектора и т.п.
А>>И никто не собирается понизить требования к объектам в STL? А>>А зачем им вообще понадобилось assignable? Чтобы двигать их по памяти, думаю, достаточно copy constructable.
ГА>Можно даже не доходить до вопросов реализации, а задуматься об интерфейсе. ГА>С вектором можно делать, например так: ГА>
ГА>v.push_back(value); // что делаем здесь без конструктора копии?
ГА>v[idx] = value; // а здесь - без оператора присваивания?
ГА>*iter = value;
ГА>T value = *iter;
ГА>
ГА>Чтобы быть совместимыми с интерфейсом контейнера, элементы контейнера должны быть assignable & copy constructible. Точка.
Согласен.
Но с практической точки зрения, при ограниченном применении std::deque можно обойтись только copy constructable.
#include <deque>
#include <iostream>
struct bar // copy constructable but not assignable
{
private:
bar& operator=(const bar&);
int m_n;
public:
bar(int i) : m_n(i) {}
void foo() {std::cout << m_n << '\n';}
};
int main()
{
std::deque<bar> array;
array.push_back(bar(1));
array.push_back(bar(2));
array[0].foo();
}
Я думаю просто в комитете не захотели заморачиваться над подробным описанием требований к каждому методу, так же как и с ситуацией инстанцирования шаблонов стандартной библиотеки неполными типами, просто заретили и всё.
Но конечно раз стандарт не гарантирует что в данном куске кода не понадобится assignable, то есть шанс нарваться в будущем на неприятности, хотя с практической точки зрения здесь assignable понадобиться не должен.
Здравствуйте, korzhik, Вы писали:
K>Но с практической точки зрения, при ограниченном применении std::deque можно обойтись только copy constructable.
То же можно сказать о всех node-based контейнерах. Но автору темы даже copy constructible не подходит, так что непонятно, как элементы, собственно, будут в этот контейнер попадать.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Not copy constructable & assignable
От:
Аноним
Дата:
07.12.05 10:43
Оценка:
ГА>Можно даже не доходить до вопросов реализации, а задуматься об интерфейсе. ГА>С вектором можно делать, например так: ГА> ГА>v.push_back(value); // что делаем здесь без конструктора копии?
Да, вектору здесь тяжело, а вот std::deque вполне мог бы пережить.
ГА>v[idx] = value; // а здесь — без оператора присваивания? ГА>*iter = value; ГА>T value = *iter;
А вот это уже интимные проблемы автора этого кода.
Говорим, что нету operator = при компиляции.
При этом v[idx].f() вполне прокатит, и может сделать некоторых счастливыми.
Здравствуйте, Глеб Алексеев, Вы писали:
ГА>Отсюда альтернативы: vector/list< shared_ptr<T> > (если объектов много, тяжелое решение), boost::pointer_container, vector<T*> и ручное управление временем жизни.
ГА>То же можно сказать о всех node-based контейнерах. Но автору темы даже copy constructible не подходит, так что непонятно, как элементы, собственно, будут в этот контейнер попадать.
Здравствуйте, Аноним, Вы писали:
А>Насколько я вижу, она позволит обойтись без конструктора копирования, одним operator =(). Так? А>Но он тоже не нужен.
Я прочёл сабж как (not copyconstructible) & assignable
А>Ну есть, например, окно (графическое). А>Ну, зачем ему всё это? А хранить их в ящичке хочется.
А размер ящичка заранее известен, или может меняться на ходу? Если первое — то boost::scoped_array, если второе — то извините.
И вообще, контейнеры предназначены для хранения объектов с семантикой значения. А окна таковыми не являются.
Поэтому ограниченно использовать контейнер (в надежде, что шаблон класса воплотит только те методы, которые востребованы) — ходить по тонкому льду.
А комитет по стандартизации... всё таки, класс — это вещь цельная. Говорить: вот для этого метода нужны такие требования, а для этого другие — это, во-первых, идти против цельности, а во-вторых, излишне ограничивать реализацию.
Например, конструктор vector::vector(int n) может быть сделан через zeroinit(), resize(n) — а тот требует, чтобы элементы были копируемыми. Если же мы заявим, что для vector(n) достаточно DefaultConstructible — придётся дублировать код...
Перекуём баги на фичи!
Re[4]: Not copy constructable & assignable
От:
Аноним
Дата:
07.12.05 10:52
Оценка:
B>>>Ну а что же еще, если тип не удовлетворяет поставленным требованиям? А>>Ну, взяли бы и смягчили требования. B>Поздно — слишком многое придется менять
Если менять в сторону смягчения, то менять надо только реализацию STL.
И то не иенять, а, может, местами поправить.
B>Эти алгоритмы могут использоваться внутри сомой реализации библиотеки во множестве мест.
Перепишут. Стандарт же сейчас не требует их использовать.
B>Встречный вопрос: Предложи реализацию вектора, например, в которой от элементов не требовалось бы свойсв copyconstructable & assignable
Да, вектор потенциально релокейтит свою память, для него не сделаешь.
А list, deque?
Здравствуйте, <Аноним>, Вы писали:
ГА>>Можно даже не доходить до вопросов реализации, а задуматься об интерфейсе. ГА>>С вектором можно делать, например так: ГА>> ГА>>v.push_back(value); // что делаем здесь без конструктора копии? А>Да, вектору здесь тяжело, а вот std::deque вполне мог бы пережить.
Как это????
Пусть даже не deque, а list.
void _Insert(iterator _Where,
const _Ty& _Val)
{ // insert _Val at _Where
_Nodeptr _Pnode = _Where._Mynode();
_Nodeptr _Newnode = _Buynode(_Pnode, _Prevnode(_Pnode), _Val);
_Incsize(1);
_Prevnode(_Pnode) = _Newnode;
_Nextnode(_Prevnode(_Newnode)) = _Newnode;
}
_Nodeptr _Buynode(_Nodeptr _Next,
_Nodeptr _Prev, const _Ty& _Val)
{ // allocate a node and set links and value
_Nodeptr _Pnode = this->_Alnod.allocate(1);
_TRY_BEGIN
new ((void *)_Pnode) _Node(_Next, _Prev, _Val);
_CATCH_ALL
this->_Alnod.deallocate(_Pnode, 1);
_RERAISE;
_CATCH_END
return (_Pnode);
}
struct _Node
{ // list node
_Node(_Genptr _Nextarg, _Genptr _Prevarg, const _Ty& _Myvalarg)
: _Next(_Nextarg), _Prev(_Prevarg), _Myval(_Myvalarg)
{ // construct a node with value
}
...