user2138149
user2138149

Reputation: 16625

Is this the correct way to access objects inside a list?

EDIT: TLDR? Here's a summary:

The requirement is for an essentially infinitely (or arbitrarily) long container. So list sounds like a good idea, because it will fit the objects in whatever memory space is available.

However vectors are much faster/efficient at access, but might not be able to fit in memory if we don't have a long sequential strip.

Vector of pointers was suggested to reduce memory usage, but the problem remains if there are a gigabyte of pointers and I have 4GB of ram, it might just not fit!

Solution: A list of vectors might be the way to go. Each item in the list could be a vector with 1000 pointers to items which we want to be able to access. A class could handle this functionality.

** Original Question:**

As a wise man once said: "With pointers, if it works once, that doesn't guarantee you are doing it correctly."

I have a class:

class A;

And class A is inside a std::list:

std::list<A> list_of_A;

To access items inside it I am using:

std::list<A>::iterator iter = list_of_A.begin();
std::advance(iter, <an_unsigned_int>);
return *iter;

This seems to be working, but is return *iter the correct thing to be doing? I should mention the last 3 lines are inside a function which returns a const A&.

I looked for an answer on stackoverflow, but couldn't find a duplicate of this question, which surprises me.

List > Vector because I will be swapping things in and out of the list.

Upvotes: 0

Views: 86

Answers (2)

Loki Astari
Loki Astari

Reputation: 264391

This is good as long as you have not advanced to (or past) end().

const A& stuff(std::list<A>& list_of_A, int index)
{
    assert(index <= list_of_A.size());              // Protect against UB
                                                    // of advancing past end.

    std::list<A>::iterator iter = list_of_A.begin();
    std::advance(iter, index);

    if (iter == list_of_A.end())
    {    throw std::runtime_error("Failed");       // Not allowed to de-reference end()
    }
    return *iter;
}

Upvotes: 1

Alex Chamberlain
Alex Chamberlain

Reputation: 4207

Yes; you will return a reference inside the list if your function returns A& or A const& and a copy if your function returns A.

However, if you are doing this regularly, why not use a std::vector? They have random access iterators and are almost always more efficient than a std::list, unless the objects are large and you have a large number of them. std::list are very cache-inefficient.

Upvotes: 1

Related Questions