Topic: extending the STL-containers


Author: Mattias Lundstroem <ehsmalu@aom.ericsson.se>
Date: 1997/09/10
Raw View
Richard See wrote:

> Konstantin Baumann wrote:

> > I want to create a special version of the STL-list-container. This
> > special version should be able to call a callback-function (something
> > like the publisher-subscriber-mechanism) every time the contents of
> > the container had been changed (by inserting, erasing AND writing
> > through an appropriate bidirectional iterator).

[snip]

> Your main problem will be with functions that return a reference to
> values, as these allow values to be changed at any time after a function
> call, without calling your callback function.  eg.
>
> vector<int> v(10);
> v[5] = 4;
>

> One way around this is to define a proxy class to stand in for a
> reference.  You can then provide an assignment operator for this class,
> in which you call the callback function.  (See Coplien, Advanced C++,
> Figure 3.3, or Meyers, More Effective C++, Item 30, Distinguishing Reads
> from Writes via operator[].)  The effect of this on your classes'
> interfaces is large enough to suggest that using the stl classes for
> member data rather than inheriting from them would be the best approach.
>

[snip]

If you are thinking about a solution like this it would probably be much better
to have a proxy class and use STL collections of this proxy class. You would
then escape all the problems with returning references and you do not need to
make your own collections. Ie

vector< myproxy<int> > v(10);
v[5] = 4;

Without knowing more about your problem it is difficult to say what would be the
best solution but this seems most natural to me.

-- Mattias



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Konstantin Baumann" <kostab@uni-muenster.de>
Date: 1997/08/13
Raw View
Hi!

I am looking for a way to extend the existing STL-containers to
fulfill my special needs, e.g.:

I want to create a special version of the STL-list-container. This
special version should be able to call a callback-function (something
like the publisher-subscriber-mechanism) every time the contents of
the container had been changed (by inserting, erasing AND writing
through an appropriate bidirectional iterator).

The question is:

Can I derive from the STL-containers in such a way that I only have to
reimplement the corresponding methods (only insert() and erase()) and
provide a special iterator (perhaps a more general iterator-
adapter)? But the special iterator has to keep track to which container
it belongs to, so the begin() and end() methods have also to be
rewritten! Something more?

BTW: I know there are no virtual methods and no virtual destructor.
But if I only use the new container as the new container and never
as the STL-container (by donwcasting to the base) it shouldn't
matter, should it?

Ciao, Kosta
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Kevin S. Van Horn" <ksvhsoft@xmission.com>
Date: 1997/08/14
Raw View
Konstantin Baumann wrote:
>
> I want to create a special version of the STL-list-container. This
> special version should be able to call a callback-function [...]
> every time the contents of the container had been changed [...]
>
> Can I derive from the STL-containers in such a way that I only have to
> reimplement the corresponding methods [...]

I think that what you'll have to do is use containment instead of
inheritance.  That is, your special list will have as private data
members the STL list and and your callback.  All the list functions will
then be trivial (perhaps inline) functions that just call the same
function on the contained STL list, and your callback where necessary.
You'll also have to do the same for the list iterators -- your list
iterators will contain an STL list iterator and either a pointer to the
callback or a pointer to its extended list object.

-----------------------------------------------------------------
Kevin S. Van Horn            | C++ contract programming, library design,
KSVH Software and Consulting | and flexible software components
ksvhsoft@xmission.com          http://www.xmission.com/~ksvhsoft/
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Richard See <Richard.See@vega.co.uk>
Date: 1997/08/16
Raw View
Konstantin Baumann wrote:
>
> Hi!
>
> I am looking for a way to extend the existing STL-containers to
> fulfill my special needs, e.g.:
>
> I want to create a special version of the STL-list-container. This
> special version should be able to call a callback-function (something
> like the publisher-subscriber-mechanism) every time the contents of
> the container had been changed (by inserting, erasing AND writing
> through an appropriate bidirectional iterator).
>
> The question is:
>
> Can I derive from the STL-containers in such a way that I only have to
> reimplement the corresponding methods (only insert() and erase()) and
> provide a special iterator (perhaps a more general iterator-
> adapter)? But the special iterator has to keep track to which container
> it belongs to, so the begin() and end() methods have also to be
> rewritten! Something more?

Something more.  See below.

> BTW: I know there are no virtual methods and no virtual destructor.
> But if I only use the new container as the new container and never
> as the STL-container (by donwcasting to the base) it shouldn't
> matter, should it?
>

Correct.  You could enforce this by deriving privately.  However,
derivation doesn't actually solve your problems:

All non-const member functions would need to be reimplemented, not just
insert and erase.  You would need to write a new iterator class, which
would need to be used in your interface instead of the STL iterators.
(The STL const_iterators should be reusable tho.)

Your main problem will be with functions that return a reference to
values, as these allow values to be changed at any time after a function
call, without calling your callback function.  eg.

vector<int> v(10);
v[5] = 4;

One way around this is to define a proxy class to stand in for a
reference.  You can then provide an assignment operator for this class,
in which you call the callback function.  (See Coplien, Advanced C++,
Figure 3.3, or Meyers, More Effective C++, Item 30, Distinguishing Reads
from Writes via operator[].)  The effect of this on your classes'
interfaces is large enough to suggest that using the stl classes for
member data rather than inheriting from them would be the best approach.

Another way would be to define your classes' interfaces differently from
the STL interfaces, so that they do not to return non-const references
to values.  Again, the STL containers would be contained, not inherited,
and STL const_iterators could still be used.  This would be easier, but
would result in your classes being compatible with fewer of the STL
generic algorthims.

Richard.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]





Author: Matt Austern <austern@sgi.com>
Date: 1997/08/17
Raw View
"Konstantin Baumann" <kostab@uni-muenster.de> writes:

[note:  this crosspost was accepted because comp.lang.c++.moderated is
the last group in the list. --mod]

> I want to create a special version of the STL-list-container. This
> special version should be able to call a callback-function (something
> like the publisher-subscriber-mechanism) every time the contents of
> the container had been changed (by inserting, erasing AND writing
> through an appropriate bidirectional iterator).
>
> The question is:
>
> Can I derive from the STL-containers in such a way that I only have to
> reimplement the corresponding methods (only insert() and erase()) and
> provide a special iterator (perhaps a more general iterator-
> adapter)? But the special iterator has to keep track to which container
> it belongs to, so the begin() and end() methods have also to be
> rewritten! Something more?

The STL containers were not designed for that sort of extension by
inheritance, and there's nothing in the draft standard that guarantees
that it would work.  (For one thing, every reference to "iterator" and
"const_iterator" in the base class would refer to the base class's
iterators, not to the derived class's.)

The STL was designed for a different sort of extension: if you write
your own container, and if you adhere to the standard container
requirements, then the existing STL algorithms will interoperate with
your new container.  In this particular case, I think you'll find that
writing your own container (possibly using existing containers in the
implementation) is no more work than the inheritance solution would
have been.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting
with your
                newsreader.  If that fails, use
mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy:
http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]