Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access the first element of std::list?

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();
}
like image 357
shan Avatar asked Mar 01 '13 10:03

shan


People also ask

How do you print the first element of a list in C++?

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.

How do you find the nth element of a list in C++?

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);

What does .front do in C++?

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.


Video Answer


1 Answers

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?

like image 151
LihO Avatar answered Sep 19 '22 17:09

LihO