I have a list std::list<T *> *l;
. this list is not null and has some values. My problem is how to access items properly? i do not need to iterate over the list. i just want the first item only.
std::list<T*>::iterator it = l->begin();
if (it != l->end())
{
// accessing T
int value = (*it)->value(); // Is this safe?
}
or should i check for null also?
if (it != l->end() && (*it))
{
// accessing T
int value = (*it)->value();
}
list front() function in C++ STL. Parameters: This function does not accept any parameter, it simply returns a reference to the first element in the list container. Return Value: This function returns a direct reference to the first element in the list container.
Accessing nth element in std::list using std::next() ForwardIterator next (ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1); template <class ForwardIterator> ForwardIterator next (ForwardIterator it, typename iterator_traits<ForwardIterator>::difference_type n = 1);
The C++ function std::queue::front() returns a reference to the first element of the queue. This element will be removed after performing pop operation on queue. This member function effectively calls the front member function of underlying container.
If you are forced to use std::list<T*> myList;
and let's say that T
is defined as:
struct T
{
T(const char* cstr) : str(cstr){ }
std::string str;
};
then just use std::list::front
to access first element:
std::string firstStr = myList.front()->str;
Note that in this case myList.front()
returns a reference to first element in your list, which is reference to pointer in this case. So you can treat it just like a pointer to the first element.
And to your question about the NULL
: When you work with the container of pointers, the pointer should be removed from the container once the object is destructed. Once you start using pointers, it usually means that you are the one who becomes responsible for the memory management connected with objects that these pointers point to (which is the main reason why you should prefer std::list<T>
over std::list<T*>
always when possible).
Even worse than NULL
pointers are dangling pointers: When you create an object, store its address in your container, but you will not remove this address from your container once the object is destructed, then this pointer will become invalid and trying to access the memory that this pointer points to will produce undefined behavior. So not only that you should make sure that your std::list
doesn't contain NULL
pointers, you should also make sure it contains only pointers to valid objects that still exist.
So by the time you will be cleaning up these elements, you will find yourself removing pointers from your list and deleting objects they point to at once:
std::list<T*> myList;
myList.push_back(new T("one"));
myList.push_back(new T("two"));
myList.push_back(new T("three"));
myList.push_back(new T("four"));
while (!myList.empty())
{
T* pT = myList.front(); // retrieve the first element
myList.erase(myList.begin()); // remove it from my list
std::cout << pT->str.c_str() << std::endl; // print its member
delete pT; // delete the object it points to
}
It's also worth to read these questions:
Can you remove elements from a std::list while iterating through it?
Doesn't erasing std::list::iterator invalidates the iterator and destroys the object?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With