Why can't I assign a pointer to the beginning of an STL list?

Posted on 2000-03-23
Last Modified: 2010-04-02
#include <list>

class Contig {int q;};  // The shortest class I could make


  list<Contig> AllContigs;  

  Contig whatever;   // Just something that I can push onto the list

  AllContigs.push_front( whatever ) ;

  Contig *a = (AllContigs.begin()) ; // Why doesn't this work?
  Contig &b = *(AllContigs.begin()) ; //This does work.

I guess that I am going to have to use the & operator
(is it called a reference operator?).  In the greater
scheme of things this is undoubtably good.
Nonetheless, to me pointers and lists go hand-in-hand
and I don't understand why I can march through the
list with pointers like I would in C.


Question by:klopter
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
LVL 22

Accepted Solution

nietod earned 100 total points
ID: 2649625
list::begin() returns an iterator to an item in the list.   This is LIKE a pointer, but it is not a pointer (it is a class).

LVL 22

Expert Comment

ID: 2649673
#include <list>

class Contig {int q;};  // The shortest class I could make


   list<Contig> AllContigs;  

   Contig whatever;   // Just something that I can push onto the list

   AllContigs.push_front( whatever ) ;

   list<Contig>::iterator a = (AllContigs.begin()) ;

Those list<Contig>::iterator's can get long an painful to type, so you may want to use typedef's to "shorten" them like

typedef  list<Contig>>::iterator Congig_itr;

   lContig_itr a = (AllContigs.begin()) ;

I guess I sort of missed the main question--why does the line

Contig &b = *(AllContigs.begin());

work?  This is because the iterator class that is returned by begin() overloads operator * so that operator * returns the item that the iterator refers to.   As you can see, by overloading ovperator * it makes the iterator seem like a pointer.  This is no accident.  The iterator works  like both a pointer in its function, and in the way that it is used (operator * and -> can "dereference" it, for some types of interators you can use + and - to get iterators to other items in the container, you like pointers.).   The reason this is done is that the STL defines many template algorithms that can be made to work with both pointers or iterators.  Thus you can use a sort algorithm to sort an array using pointers or to sort a vector<> using iterators.  All with the exact same template code.

Let me knw if you have any questions.

Author Comment

ID: 2650040
So, I take it that the right thing to
do is to use iterators.  

I am worried that my code is going to
become unreadable to my non-STL
compatible fellow workers, but I
will continue for now.

Here is what I am trying to create:
A list of items that I call contigs.
Each contig may have an arbitrary
number (typically 2) of neighbors to
the left, and an arbitrary
number of neighbors to
the right.  This graph of contigs
is symmetric in that if b is a's
neighbor to the left, a is b's neighbor
to the right.

I want the contigs to be a list rather
than a vector because I want to
be able to add and delete contigs.

I have a class named Contig which seems
to give me close to what I want.
But, on the other hand I may be a long
way off.

here is the code.  It is also at:

My current struggle is in getting the
last line to compile.  (Making sure
that b is a's neighbor to the left.)


#include <list>
#include <assert.h>
#include <string>

class Contig {

  list<Contig*> left;
  list<Contig*> right;
  char *id; // This is just for debug

  void AddLeft( Contig &c ) ;
  void RemoveLeft( Contig &c ) ;

  Contig( );
  ~Contig( );


Contig::Contig() {
  id = (char *) NULL ;

Contig::~Contig() {
  if ( id ) cerr << " id = " << id << endl ;
  cerr << " Here we are in ~Contig" << endl ;

void Contig::AddLeft(  Contig &c ) {  // I started with Contig *c as the argument here, but &c seems to work better

  left.push_front( &c ) ;
  c.right.push_front( this ) ;

void Contig::RemoveLeft(  Contig &c ) {

  left.remove( &c ) ;
  c.right.remove( this ) ;

typedef  list<Contig>::iterator Contig_itr;


  list<Contig> AllContigs;

  Contig whatever;  // I don't really want this Contig, but I need something
  // to pass to  AllContigs.push_front = "whatever";   // This belongs in a constructor, but id is only for debug anyway.

  AllContigs.push_front( whatever ) ;
  Contig_itr a = (AllContigs.begin()) ;
  a->id = "A";
  AllContigs.push_front( whatever ) ;
  Contig_itr b = (AllContigs.begin()) ;
  b->id = "B";

  a->AddLeft(*b);  // This should set a.left = b and b.right = a

  assert( a == b ) ;
  assert( *(a->left.begin()) == b ) ;   // I can't get this to work.

LVL 22

Expert Comment

ID: 2650100
>> I am worried that my code is going to
>> become unreadable to my non-STL
>> compatible fellow workers, but I
>> will continue for now
I'd be worried that it will be unreadable to me.

Using STL is definitely a change, but its not that big a change.  You might be feelign a bit overwhelmed af first, but that will pass quicky.  its probably a bit like the first time you programmed in C++ instead of C (assuming you made the switch) and saw all those weird ::'s and <>'s etc.

>> I want the contigs to be a list rather
>> than a vector because I want to
>> be able to add and delete contigs.
You can add and delete to both.  But if you will be doing lots of adding and deleting, the a list will be more efficient.

LVL 22

Expert Comment

ID: 2650169
>>  Contig whatever;  // I don't really want this Contig, but I need something
>>                // to pass to  AllContigs.push_front

ideally, you would add a constructor to Contig, either a default constructor, or one that specifies values for the data embers you need to have set, like ID, so then instead of

                AllContigs.push_front( whatever ) ;
                Contig_itr a = (AllContigs.begin()) ;
                a->id = "A";

you can do.

                AllContigs.push_front(Contigs("A") ) ;


>>  assert( a == b ) ;

But this is not true.  a is now the 2nd item because b is the new first item.

>> assert( *(a->left.begin()) == b ) ;   // I can't get this to work.
These aren't equal either.  Does this compile?
b is an iterator of type list<Config>::iterator.  the a->left.begin() returns an iterator of type list<Config *>::iterator.  then you do an * on this so you get a Config* on the left.  

You want to see if the two are at the same address, so you could do

assert( *(a->left.begin()) == &(*b))

nice huh?  Actually this ugliness has nothing to do with STL.  If you did the same thing with pointers and linked lists you would have the exact same issues and code.

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
mixing C++ & C# in Vis Studio 2013 7 280
thread-safe code in c++ 2 128
Using Diagnostic tools in VS2015: Unresoved allocations 19 147
maximize the sum of fractions 33 75
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question