У меня есть std::list<T>
, где T
имеет некоторые функции-члены, в частности конструктор T
, который хотел бы сообщить некоторым другим классам об адресе T
в list<T>
.Это так, чтобы другие классы могли позже удалить этот узел / склеить его в другой список / и т. Д.
При построении T
еще не имеет места в списке, поэтому сейчас он просто выдаетсвой собственный адрес (через T::this
).Мне было интересно, может ли это T*
быть конвертируемым в list<T>::iterator
, который затем сделал бы доступными стандартные контейнерные операции для удаления / передачи / и т. Д.
Кажется, что нет немедленного ответа (для списков) в этот вопрос .Я думаю, что один из обходных путей - добавить новое поле list<T>::iterator
к T
и написать правильное значение, как только оно станет известным.Классы, которые могут обращаться к T
, могут затем обращаться к правильному итератору.
Интересно, что представляется возможным свернуть мою собственную наивную реализацию узла списка в T
.В этой модели T инкапсулирует свои собственные возможности списка, так что каждый T также является узлом списка, а каждый T * является итератором списка.Это решило бы мою проблему.(Грубый набросок приведен ниже для интереса.) Я не встроил это в полноценный контейнер, так как кажется, что для его правильной реализации достаточно много работы ( как здесь ).Так что я думаю, что я буду использовать обходной путь, если у сообщества нет каких-либо предложений?Большое спасибо.
/* Base class for T provides list capabilities. Usage T : node<T>. */
template< class T >
struct node
{
node<T>* next_; /* forward list. */
/* Here the value is contained *outside* the node: */
T* value() { return static_cast<T*> this; } /* uh-oh */
}
/* The iterator is essentially a convenience wrapper around node<T>*,
can define operator++() etc. */
template< class T >
struct list<T>::iterator
{
iterator( node<T>* some_node ) : node_( some_node );
iterator operator++() { return node_ = node_->next_; }
/* etc. */
node<T>* node_;
}
/* Usage: */
class Example : public node< Example >
{
/* iterator is directly constructible from node< Example >*,
and Example derives from node< Example >, so class can
construct its own iterator. */
operator list< Example >::iterator() { return this; }
/* Example's data members here as usual. */
float data1_;
}