Re[7]: Реализация дерева средствами с++11
От: -MyXa- Россия  
Дата: 16.04.16 14:27
Оценка:
Здравствуйте, _hum_, Вы писали:

__>Здравствуйте, -MyXa-, Вы писали:


MX>>Здравствуйте, _hum_, Вы писали:


__>>>кстати, оказывается, std::experimental::observer_ptr


MX>>На сколько мне известно, он ничего не делает.



__>да, так и написано:


__>

__>It is intended as a near drop-in replacement for raw pointer types, with the advantage that, as a vocabulary type, it indicates its intended use without need for detailed analysis by code readers.


Вот именно, что как reader, я сразу напрягусь и пойду искать — каким это таким незаконным способом ты этот указатель получил, и почему это observer_ptr гуляет по лесу один так далеко от того места, где его получили.

MX>> Это просто удобный способ отметить где у тебя, скорее всего, ошибка в программе.


__>?


Раньше у нас была куча легаси и голые указатели, теперь у нас везде observer_ptr, но программа падает ровно в тех же местах.
Если не поможет, будем действовать током... 600 Вольт (C)
Re[4]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 16.04.16 14:53
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Здравствуйте, _hum_, Вы писали:


SVZ>>>Предлагаю "ход конём". Заменить указатели на индексы в массиве.


__>>ну, тогда ж придется писать аналог менеждера кучи (чтоб искал свободное место, куда можно вставлять новые элементы, чтобы помечал удаленные как свободные места и т.п.). но еще чуть-чуть, и я психану и все же наверное так и сделаю, потому что тратить столько времени на реализацию обычного дерева — это уж слишком (а я уже третий день с этим вожусь)


SVZ>Ох уж эта молодёжь...


SVZ>Вот получение узла из "менеджера кучи":


  code
SVZ>
SVZ>// ==========================================================================
SVZ>// Создать узел
SVZ>dom::NODE dom::Document::makeNode(LPCTSTR name)
SVZ>{
SVZ>    dom::NODE nodeN = m_NodeFreeList;
SVZ>    if ( nodeN < 0 )
SVZ>    {
SVZ>        nodeN = static_cast<dom::NODE>(m_InfoNode.size());
SVZ>        m_InfoNode.push_back( NodeInfo() );
SVZ>    }
SVZ>    else
SVZ>    {
SVZ>        m_NodeFreeList = m_InfoNode[nodeN].next;
SVZ>        m_InfoNode[nodeN] = NodeInfo();
SVZ>    }

SVZ>    NAMEREF nref = makeNodeName(name);
SVZ>    m_InfoNode[nodeN].name = nref;

SVZ>    return nodeN;
SVZ>}
SVZ>

SVZ>Удаленные узлы помещаются в односвязный список, голова которого хранится в m_NodeFreeList.
SVZ>Хранить можно и плоский список, и целые поддеревья (только в makeNode придется этот факт учитывать), в общем пространство для маневра обширное.

SVZ>Свой код не привожу, потому что у меня там хитрое владение именами узлов — не думаю, что тебе это пригодится.


SVZ>По сложности — задачка на пару часов для студента 2 курса.


кстати, в таком же варианте, если не заморачиваться, то придется сериализовывать и список свободных вершин, а значит, сериализация будет всегда давать максимально возможный объем, что не есть гуд.
Re[6]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 16.04.16 14:55
Оценка:
Здравствуйте, -MyXa-, Вы писали:

MX>Здравствуйте, _hum_, Вы писали:


__>>ясно что — делал бы клонирование (в противном бы случае удаление одного объекта привело бы к некорректной работе другого). в случае же с shared клонирование необязательно — два объекта могу работать через шареды с одним и теми же узлами.


MX>Так это-ж больше от задачи зависит. Надо клонировать — клонируй, не надо — не клонируй.


это ходить по острию — если unique_ptr просто даст вам по рукам при попытке скопировать, то шаред, который изначально создавался под раздельное владение, просто проигнорирует, и ждите сюрпризов.
Re[8]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 16.04.16 14:59
Оценка:
Здравствуйте, -MyXa-, Вы писали:

MX>Здравствуйте, _hum_, Вы писали:


__>>Здравствуйте, -MyXa-, Вы писали:


MX>>>Здравствуйте, _hum_, Вы писали:


__>>>>кстати, оказывается, std::experimental::observer_ptr


MX>>>На сколько мне известно, он ничего не делает.



__>>да, так и написано:


__>>

__>>It is intended as a near drop-in replacement for raw pointer types, with the advantage that, as a vocabulary type, it indicates its intended use without need for detailed analysis by code readers.


MX>Вот именно, что как reader, я сразу напрягусь и пойду искать — каким это таким незаконным способом ты этот указатель получил, и почему это observer_ptr гуляет по лесу один так далеко от того места, где его получили.


при чем тут незаконным? вам не надо ничего искать, вам сразу говорят, что он никем не владеет, и просто является средством доступа к объекту (еще бы добавили к нему возможность узнавать, существует ли объект, который ему дали при создании, или нет, и было бы вообще здорово).

MX>>> Это просто удобный способ отметить где у тебя, скорее всего, ошибка в программе.


__>>?


MX>Раньше у нас была куча легаси и голые указатели, теперь у нас везде observer_ptr, но программа падает ровно в тех же местах.


это только означает, что нет статистической связи между "ошибка в вашей программе" и "использование observer_ptr"
Re[7]: Реализация дерева средствами с++11
От: -MyXa- Россия  
Дата: 16.04.16 15:29
Оценка:
Здравствуйте, _hum_, Вы писали:

__>это ходить по острию — если unique_ptr просто даст вам по рукам при попытке скопировать, то шаред, который изначально создавался под раздельное владение, просто проигнорирует, и ждите сюрпризов.


Ну, какие проблемы? Сделай шареды деталью реализации, наружу выстави классы с нужной тебе семантикой.

А так-то да, везде свои трудности, голые указатели — голые, шареды — копируются, сборщик мусора..., впрочем, не будем об этом.
Если не поможет, будем действовать током... 600 Вольт (C)
Re[5]: Реализация дерева средствами с++11
От: Stanislav V. Zudin Россия  
Дата: 16.04.16 16:04
Оценка:
Здравствуйте, _hum_, Вы писали:

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


Да, есть такое. Если у нас есть завязки на узлы дерева, то уплотнять всё дерево и перестраивать связи может быть муторно, особенно, если необходима поддержка отката.
Но с другой стороны, если это,скажем, редактор, то операций добавления всё же больше, чем удаления. Поэтому незадействованных узлов оказывается пренебрежимо мало.
_____________________
С уважением,
Stanislav V. Zudin
Re[8]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 16.04.16 16:51
Оценка:
Здравствуйте, -MyXa-, Вы писали:

MX>Здравствуйте, _hum_, Вы писали:


__>>это ходить по острию — если unique_ptr просто даст вам по рукам при попытке скопировать, то шаред, который изначально создавался под раздельное владение, просто проигнорирует, и ждите сюрпризов.


MX>Ну, какие проблемы? Сделай шареды деталью реализации, наружу выстави классы с нужной тебе семантикой.



проблемы в том, что вы пытаетесь использовать только часть семантики shared_ptr/weak_ptr там, где по семантике должны стоять unique_ptr/observer_ptr (дерево обычно одно на объект, а не "разделяемое" между многими объектами)

MX>А так-то да, везде свои трудности, голые указатели — голые, шареды — копируются, сборщик мусора..., впрочем, не будем об этом.


просто чувствуется нехватка для unique_ptr полноценного напарника типа observer_ptr...
Re[6]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 16.04.16 16:55
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Здравствуйте, _hum_, Вы писали:


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


SVZ>Да, есть такое. Если у нас есть завязки на узлы дерева, то уплотнять всё дерево и перестраивать связи может быть муторно, особенно, если необходима поддержка отката.

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

да, но если у кого-то залипнет клавиша вставки (или он просто побалуется), а потом он все лишнее удалит, то файл проекта будет огромный

п.с. пока остановился на варианте с функциями конвертации дерева из обычного в "на смартах (без parenta)"[для сериализации] и обратно
Re[3]: Реализация дерева средствами с++11
От: Ops Россия  
Дата: 16.04.16 22:51
Оценка: +1
Здравствуйте, _hum_, Вы писали:

__>проблема возникла из : нужно организовать дерево, которое бы можно было сериализовать с помощью библиотеки cereal (она самая лекговесная и удобная из виденных мною). последняя умеет работать только с умными указателями.


А если не сериализовывать этот указатель вообще? А после (или в процессе, смотря как оно сделано) десереализации обойти дерево и присвоить нужные значения.
Библиотеку не знаю, так что все умозрительно.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re: Реализация дерева средствами с++11
От: Erop Россия  
Дата: 17.04.16 07:09
Оценка:
Здравствуйте, _hum_, Вы писали:

__>p.s. T4r4sB, это же вы, по-моему, недавно говорили, что raw-ptr устарели


Для начала тут интересно бы понять ответы на несколько вопросов.

1) Зачем вообще узлу владеть детьми? Почему узлу, а не дереву?
2) Если объекты как-то геморрно и сложно конструируются, то зачем им вообще лежать в узлах, а не в параллельном массиве, например, или по указателям или ещё как?

Например, если структуру ссылок в бинарном дереве хранить как-то так:
struct node_offsets {
    int parent_offset;
    enum { left_child_offset = 1 };
    int right_child_offset;
};


А хранить их в std::vector<struct node_offsets>, то
1) можно сразу написать методы
struct node_offsets {
    int parent_offset;
    enum { left_child_offset = 1 };
    int right_child_offset;
    
    node_offsets* get_patent() { return  get_by_offset( parent_offaset ); }
    node_offsets* get_left() { return  this + left_child_offset; }
    node_offsets* get_right() { return  get_by_offset( right_child_offset ); }
private:
    node_offsets* get_by_offset( int offset ) { return offset != 0 ? this + offset : 0; }    

};


2) А ещё можно по cur_node — &vector_of_nodes[0] сразу получить id узла,

3)а сам вектор можно заменить на контейнер, который сразу из файла буфер н память отображает и т. д...
А данные узлов можно вообще в параллельном векторе хранить, например
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Реализация дерева средствами с++11
От: Erop Россия  
Дата: 17.04.16 09:52
Оценка:
Здравствуйте, _hum_, Вы писали:

__>так точно. в этом и проблема.



А в чём проблема?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 17.04.16 10:46
Оценка:
Здравствуйте, Ops, Вы писали:

Ops>Здравствуйте, _hum_, Вы писали:


__>>проблема возникла из : нужно организовать дерево, которое бы можно было сериализовать с помощью библиотеки cereal (она самая лекговесная и удобная из виденных мною). последняя умеет работать только с умными указателями.


Ops>А если не сериализовывать этот указатель вообще? А после (или в процессе, смотря как оно сделано) десереализации обойти дерево и присвоить нужные значения.

Ops>Библиотеку не знаю, так что все умозрительно.

да, была такая идея, но остановило, что по сложности восстановление парентов не многим меньше, чем полностью конвертация дерева из обычного в "smart-based". а если учесть, что юниками намного сложнее манипулировать, все-таки решил остановиться на варианте дерева на полностью голых указателях с последующей конвертацией для сериализации.
Re[2]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 17.04.16 11:11
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, _hum_, Вы писали:


__>>p.s. T4r4sB, это же вы, по-моему, недавно говорили, что raw-ptr устарели


E>Для начала тут интересно бы понять ответы на несколько вопросов.


E>1) Зачем вообще узлу владеть детьми? Почему узлу, а не дереву?


как мне видится, есть два взгляда на деррево:
1) как дерево поддеревьев, и тогда узел — это всегда корень поддерева (а значит, его существование неразрывно связано с существованием всех подузлов этого поддерева);
2) как набор узлов со специфической структурой (и тут владельцем узлов может быть уже кто-то другой).

и да, наверное мнен удобнее все-таки работать с вариантом 2), потому хорошо бы было все организовать на observer_ptr.

E>2) Если объекты как-то геморрно и сложно конструируются, то зачем им вообще лежать в узлах, а не в параллельном массиве, например, или по указателям или ещё как?


ну, тем самым вы усложняете структуру, откуда пойдет усложнение конструкторов копирования, операторов присваивания, деструкторов

E>Например, если структуру ссылок в бинарном дереве хранить как-то так:

  code
struct node_offsets {
E>    int parent_offset;
E>    enum { left_child_offset = 1 };
E>    int right_child_offset;
E>};


E>А хранить их в std::vector<struct node_offsets>, то

E>1) можно сразу написать методы
struct node_offsets {
E>    int parent_offset;
E>    enum { left_child_offset = 1 };
E>    int right_child_offset;
    
E>    node_offsets* get_patent() { return  get_by_offset( parent_offaset ); }
E>    node_offsets* get_left() { return  this + left_child_offset; }
E>    node_offsets* get_right() { return  get_by_offset( right_child_offset ); }
E>private:
E>    node_offsets* get_by_offset( int offset ) { return offset != 0 ? this + offset : 0; }    

E>};

E>2) А ещё можно по cur_node — &vector_of_nodes[0] сразу получить id узла,

E>3)а сам вектор можно заменить на контейнер, который сразу из файла буфер н память отображает и т. д...

E>А данные узлов можно вообще в параллельном векторе хранить, например

уже ж про это выше говорилось (см. обсуждение с Stanislav V. Z). вы просто забываете про редактирование (вставку, удаление).
Re[4]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 17.04.16 11:14
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, _hum_, Вы писали:


__>>так точно. в этом и проблема.



E>А в чём проблема?


в том, что с++ не дает возможности естественно отразить это различие ("указатели "вниз" и "вверх" должны быть разными") на языке смартов.
Re[3]: Реализация дерева средствами с++11
От: Erop Россия  
Дата: 17.04.16 11:33
Оценка:
Здравствуйте, _hum_, Вы писали:

__>1) как дерево поддеревьев, и тогда узел — это всегда корень поддерева (а значит, его существование неразрывно связано с существованием всех подузлов этого поддерева);

__>2) как набор узлов со специфической структурой (и тут владельцем узлов может быть уже кто-то другой).

IMHO, эти вопросы вообще не связаны. Например, можно поддержать GC для узлов, и вообще забить на владение внутри дерева...

__>и да, наверное мнен удобнее все-таки работать с вариантом 2), потому хорошо бы было все организовать на observer_ptr.

Это зависит от потребных операций. Для начала создавать/рушить эту структуру довольно долго...

__>ну, тем самым вы усложняете структуру, откуда пойдет усложнение конструкторов копирования, операторов присваивания, деструкторов

Каких деструкторов? В той структуре, которую я предложил, связи в дереве задаются POD-структурами, без конструкторов/деструкторов...

__>уже ж про это выше говорилось (см. обсуждение с Stanislav V. Z). вы просто забываете про редактирование (вставку, удаление).


А чем тут так сложна вставка/удаление?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Реализация дерева средствами с++11
От: Erop Россия  
Дата: 17.04.16 11:35
Оценка:
Здравствуйте, _hum_, Вы писали:

__>в том, что с++ не дает возможности естественно отразить это различие ("указатели "вниз" и "вверх" должны быть разными") на языке смартов.


IMHO, это не С++ не даёт, а твои установки или инструменты. Напримр юник_птр на детей, и простой на родителя, если дерево вообще нужно прошитое...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Реализация дерева средствами с++11
От: Erop Россия  
Дата: 17.04.16 11:37
Оценка:
Здравствуйте, _hum_, Вы писали:

__>да, была такая идея, но остановило, что по сложности восстановление парентов не многим меньше, чем полностью конвертация дерева из обычного в "smart-based". а если учесть, что юниками намного сложнее манипулировать, все-таки решил остановиться на варианте дерева на полностью голых указателях с последующей конвертацией для сериализации.


А зачем для сериализации куда-то конвертировать?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 17.04.16 11:59
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, _hum_, Вы писали:


__>>1) как дерево поддеревьев, и тогда узел — это всегда корень поддерева (а значит, его существование неразрывно связано с существованием всех подузлов этого поддерева);

__>>2) как набор узлов со специфической структурой (и тут владельцем узлов может быть уже кто-то другой).

E>IMHO, эти вопросы вообще не связаны. Например, можно поддержать GC для узлов, и вообще забить на владение внутри дерева...


конечно, можно делать все, как хочешь. речь же шла о наиболее естественном (для задачи) представлении.

__>>и да, наверное мнен удобнее все-таки работать с вариантом 2), потому хорошо бы было все организовать на observer_ptr.

E>Это зависит от потребных операций. Для начала создавать/рушить эту структуру довольно долго...

для двоичного не дольше O(N) — N -число узлов

__>>ну, тем самым вы усложняете структуру, откуда пойдет усложнение конструкторов копирования, операторов присваивания, деструкторов

E>Каких деструкторов? В той структуре, которую я предложил, связи в дереве задаются POD-структурами, без конструкторов/деструкторов...

вы же предложили объекты (атрибуты узла) держать отдельно, делая на них ссылки. вот те объекты нужно будет как-то удалять при разрушении дерева и копировать при создании копии.

__>>уже ж про это выше говорилось (см. обсуждение с Stanislav V. Z). вы просто забываете про редактирование (вставку, удаление).


E>А чем тут так сложна вставка/удаление?


при том, что у вас при этом начнут образовываться дырки в массиве, которые нужно будет отслеживать и заполнять, а это уже отдельная задача.
Re[6]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 17.04.16 12:02
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, _hum_, Вы писали:


__>>в том, что с++ не дает возможности естественно отразить это различие ("указатели "вниз" и "вверх" должны быть разными") на языке смартов.


E>IMHO, это не С++ не даёт, а твои установки или инструменты. Напримр юник_птр на детей, и простой на родителя, если дерево вообще нужно прошитое...


Erop, я же несколько раз повторил, что проблема — как все перевести на язык смартов ил признать, что смарты не смогут во всем заменить простые указатели.
Re[6]: Реализация дерева средствами с++11
От: _hum_ Беларусь  
Дата: 17.04.16 12:03
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, _hum_, Вы писали:


__>>да, была такая идея, но остановило, что по сложности восстановление парентов не многим меньше, чем полностью конвертация дерева из обычного в "smart-based". а если учесть, что юниками намного сложнее манипулировать, все-таки решил остановиться на варианте дерева на полностью голых указателях с последующей конвертацией для сериализации.


E>А зачем для сериализации куда-то конвертировать?


затем, что библиотека сериализации cereal, которой я пользуюсь (да наверное и остальные)работает только с stl-овскими объектами, в частности, только с умными указателями.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.