Topic: proposal for forward declaration of stl container iterator


Author: pavel@despammed.com ("Pavel Kuznetsov")
Date: Wed, 5 Mar 2003 17:46:26 +0000 (UTC)
Raw View
"Charles Wood" (c.r.wood@gte.net.no_spam) wrote:

CW> How is that incomplete?

CW> map< int, item * /*Pointer to an item*/,less<int> > collection;

Ahem... Probably I was thinking about something different, and just
overlooked that your code uses pointers, sorry, please discard my remark.

But nevertheless your solution is not for the same problem original
poster was talking about. If I understand him correctly his concern
is not about containers of pointers, but rather about containers
of elements `themselves'.

--
Pavel

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c.r.wood@gte.net.no_spam ("Charles Wood")
Date: Wed, 5 Mar 2003 21:50:25 +0000 (UTC)
Raw View
""Pavel Kuznetsov"" <pavel@despammed.com> wrote in message
news:b44a16$1qqq2k$1@ID-97366.news.dfncis.de...
: "Charles Wood" (c.r.wood@gte.net.no_spam) wrote:
:
: CW> How is that incomplete?
:
: CW> map< int, item * /*Pointer to an item*/,less<int> > collection;
:
: Ahem... Probably I was thinking about something different, and just
: overlooked that your code uses pointers, sorry, please discard my remark.
:
: But nevertheless your solution is not for the same problem original
: poster was talking about. If I understand him correctly his concern
: is not about containers of pointers, but rather about containers
: of elements `themselves'.

    The OP's problem (aside from the proxy) is that the class is undefined
when it's instantiated, well defined.  To remove that "bug" (which I don't
consider it to be) from C++ would affect so much, and make the compiler read
the files multiple times.  There would be redundecies, and total mayhem
(exagerrating).  My compile time is long enough, so I can't imagine what
that would do to it.

    Therefore I showed him the normal response to the question:  Why can't I
put one class in another and vice versa?

    Charles.

: Pavel
:
: ---
: [ 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    ]
: [              --- Please see the FAQ before posting. ---               ]
: [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]
:

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gii_anma@mariani.ws (Gianni Mariani)
Date: Thu, 6 Mar 2003 00:33:01 +0000 (UTC)
Raw View
Charles Wood wrote:
> "Gianni Mariani" <gianni@mariani.ws> wrote in message
> news:b3qpb0$an5@dispatch.concentric.net...
> :
> : Elements of a container should "know" how to remove themselves.
>
>     See this version that works "C++" unchanged.  Please be nice, my
> compiler is old.
>
> namespace std { };   //Local hack omit if you want
> #include <map>
> #include <iostream>
> #include <algo>
>
> using namespace std;
>
> class item;
> typedef map< int , item*, less< int> > collection;

As per the proposal, I want this to be:

typedef map< int , item, less< int> > collection - which can't be done
with the current stl.

I don't want the overhead of the container using just a pointer - I want
it to contain the whole object.

I want it to make it so that if the containter erases the "item", it
will also delete "item".

My proposal specifically talks only about the the object being contained
and this example contains a pointer.  The pointer knows nothing about
how to remove itself !

Your example is fine, I've also implemented all kinds of schemes to use
smart pointers that do what you suggest and more, but this is not the
issue.  This is all overhead required because of the restrictive
interface given by the stl.

The proposal presented is simply to change or add a new interface that
would mean that you don't have this unnessasary overhead.  There are
numerous ways of doing this which I specifically did not propose.  I
want there to be a concensus that this is an issue first.

The reason I specifically want this is because I have plenty of old C
code that uses this paradigm with trees and lists and It would help alot
if it I could map it to stl.


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gii_anma@mariani.ws (Gianni Mariani)
Date: Thu, 6 Mar 2003 00:33:13 +0000 (UTC)
Raw View
Philippe Mori wrote:
>>Elements of a container should "know" how to remove themselves.
>>
>>However the stl interface makes it impossible to create such a class
>>because the interator is not defined until the container element is
>>defined, hence the catch 22.
>>
>>I propose that an iterator for a list, *map or *hash container be able
>>to be forward declared and so that an element is able to contain it's
>>own iterator.
>>
>>
>
>
> You would also need that each items knows the container... So this
> will not be as lightweight as possible...
>
> Make a proxy and uses it everywhere except in the container itself:
>
> template <typename Container>
> class Proxy {
> public:
>    Proxy(Container &C_, typename Container::iterator It_) :
>     C(C_), It(It_) {}
>
>    typename Container::value_type operator->()
>       { return *It; }
>
>    typename const Container::value_type operator->() const
>       { return *It; }
>
>    void kill() { C.erase(it); }
>
> private:
>    Container &C;
>    typename Container::iterator It;
> };
>
> Using a "lightweight" proxy like that would also add the
> benefit that if you avoid the overhead for storing a
> reference to the container and an iterator (2 times 4 bytes
> on a typical 32 bits machine).

I don't understand this statement.  How are you avoiding this ?

If the data is light (for. ex.
> 1 long per item) and you have a lot of them (some millions)
> you would waste a lot of MB of memory if that information
> is permanently stored but only a few items are used at a time.

If I implemented my own container, I would be able to avoid ALL overhead
and still have the benefit of an stl-like interface.  My proposal is to
make it so this can be done.

The STL is good, don't get me wrong.  I use it most of the time, and
most of the time I know I'm doing busy work (creating proxies etc) that
is artificial i.e. No purpose other than to satisfy the shortcomings of
the interface.

Another proposal I have is to manage multi-container constructs (where
multiple containers point to the same object).  This becomes incredibly
tricky because of the limitation addressed in this proposal.  It just
dosn't need to be this way.


---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: cdotrdotwood@verizondotnet.removeme ("C Wood")
Date: Thu, 6 Mar 2003 19:34:42 +0000 (UTC)
Raw View
"Gianni Mariani" <gii_anma@mariani.ws> wrote in message
news:b4509c$an5@dispatch.concentric.net...

: > class item;
: > typedef map< int , item*, less< int> > collection;
:
: As per the proposal, I want this to be:
:
: typedef map< int , item, less< int> > collection - which can't be done
: with the current stl.

    Nor with any normal type either (assuming an aggregate object of
undefined type & size)
:
: I don't want the overhead of the container using just a pointer - I want
: it to contain the whole object.

    This opens a can of worms so big we'd have to...  Hmm, can't think of a
fix for worms.
:
: I want it to make it so that if the containter erases the "item", it
: will also delete "item".

    I don't understand your statement.  You don't want to use pointers, but
you want it to be deleted?    I'm not making fun here, I just don't
understand that request.

:
: My proposal specifically talks only about the the object being contained
: and this example contains a pointer.  The pointer knows nothing about
: how to remove itself !

    Of course it doens't, it's a pointer.  But the object pointed to in my
example can remove itself, as shown in the example.  When the pointer is
deleted, whether by the container or another function, it's removed from the
container.

:
: Your example is fine, I've also implemented all kinds of schemes to use
: smart pointers that do what you suggest and more, but this is not the
: issue.  This is all overhead required because of the restrictive
: interface given by the stl.

    That restriction is not IN the STL, it's in the language.  For example
the following will not compile:

    class a;

    class b {
        a it;
        }

    class a {
        b it;
        }

    Not a thing to do with the STL.  It's a whole mess of a rewrite.   How
to create a structure of unknown size?  That's the problem.
:
: The proposal presented is simply to change or add a new interface that
: would mean that you don't have this unnessasary overhead.  There are
: numerous ways of doing this which I specifically did not propose.  I
: want there to be a concensus that this is an issue first.

    1 vote negative here.

: The reason I specifically want this is because I have plenty of old C
: code that uses this paradigm with trees and lists and It would help alot
: if it I could map it to stl.

    I'd have to say that C++ isn't an intrepreted language.  It's still
compiled, and although it can do many eloquent things, many of those
eloquent things require pointers.   Your request isn't so much with the STL,
as I stated, it's with the language itself.  If your C stuff works, use it.
If you want to migrate it to STL, then do so.  If you want to make your own
containers, then do it.   But your change your propose is so widespread, I
doubt you will still be working on this project when things like this happen
to the language, if not writing code at all anymore (retirement).

    I'd like to see these things you ask too; although I'm not to sure of
the end effects.   I'm also not a moderator here, or anyone that's really
going to effect your life in any major way.   There isn't anything I see to
be impossible to do with C++ that can be done with other languages when
looking at the end effect.  So in that sense that way it is now is very
good.   Templates allow you to do many spectacular things, even with their
limitations imposed by the language itself.   Given enough time, I could
easy write a container that would hold objects that could be in many
containers.  When an object is erased/removed whatever, it would be removed
from all of them.  The end user wouldn't even know I'm using a pointer or
other such proxy construct.  All with STD C++, the name of this NG.

    Good luck

    Charles.

:
: ---
: [ 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    ]
: [              --- Please see the FAQ before posting. ---               ]
: [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]
:

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gianni@mariani.ws (Gianni Mariani)
Date: Mon, 3 Mar 2003 03:38:15 +0000 (UTC)
Raw View
Elements of a container should "know" how to remove themselves.

However the stl interface makes it impossible to create such a class
because the interator is not defined until the container element is
defined, hence the catch 22.

I propose that an iterator for a list, *map or *hash container be able
to be forward declared and so that an element is able to contain it's
own iterator.



---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: philippe_mori@hotmail.com ("Philippe Mori")
Date: Tue, 4 Mar 2003 06:08:36 +0000 (UTC)
Raw View
>
> Elements of a container should "know" how to remove themselves.
>
> However the stl interface makes it impossible to create such a class
> because the interator is not defined until the container element is
> defined, hence the catch 22.
>
> I propose that an iterator for a list, *map or *hash container be able
> to be forward declared and so that an element is able to contain it's
> own iterator.
>
>

You would also need that each items knows the container... So this
will not be as lightweight as possible...

Make a proxy and uses it everywhere except in the container itself:

template <typename Container>
class Proxy {
public:
   Proxy(Container &C_, typename Container::iterator It_) :
    C(C_), It(It_) {}

   typename Container::value_type operator->()
      { return *It; }

   typename const Container::value_type operator->() const
      { return *It; }

   void kill() { C.erase(it); }

private:
   Container &C;
   typename Container::iterator It;
};

Using a "lightweight" proxy like that would also add the
benefit that if you avoid the overhead for storing a
reference to the container and an iterator (2 times 4 bytes
on a typical 32 bits machine). If the data is light (for. ex.
1 long per item) and you have a lot of them (some millions)
you would waste a lot of MB of memory if that information
is permanently stored but only a few items are used at a time.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c.r.wood@gte.net.no_spam ("Charles Wood")
Date: Tue, 4 Mar 2003 06:08:36 +0000 (UTC)
Raw View
"Gianni Mariani" <gianni@mariani.ws> wrote in message
news:b3qpb0$an5@dispatch.concentric.net...
:
: Elements of a container should "know" how to remove themselves.

    See this version that works "C++" unchanged.  Please be nice, my
compiler is old.

namespace std { };   //Local hack omit if you want
#include <map>
#include <iostream>
#include <algo>

using namespace std;

class item;
typedef map< int , item*, less< int> > collection;

class item {
 public:
 private:
 collection::iterator ithis;
 collection &owner;
 public:
 item(collection &iowner,int v):owner(iowner) {
  ithis = owner.insert(owner.begin(), pair<const int, item*>(v, this)
   );
  }
 ~item() {
  owner.erase(ithis);
  }
 };

void dump_it(collection::value_type p) {
 cout << p.first << "-" << p.second << endl;
 }

int main() {
 collection it;
 item a(it,17);
  {
  item b(it,18);
   {
   item c(it,22);
         cout << "Contents:" << endl;
   for_each(it.begin(),it.end(),dump_it);
   }
  cout << "Contents:" << endl;
  for_each(it.begin(),it.end(),dump_it);
  }
 cout << "Contents:" << endl;
 for_each(it.begin(),it.end(),dump_it);
 return 0;
 };


:
: However the stl interface makes it impossible to create such a class
: because the interator is not defined until the container element is
: defined, hence the catch 22.
:
: I propose that an iterator for a list, *map or *hash container be able
: to be forward declared and so that an element is able to contain it's
: own iterator.
:
:
:
: ---
: [ 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    ]
: [              --- Please see the FAQ before posting. ---               ]
: [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]
:

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pavel@despammed.com ("Pavel Kuznetsov")
Date: Tue, 4 Mar 2003 19:23:27 +0000 (UTC)
Raw View
Charles Wood (c.r.wood@gte.net.no_spam) wrote:

CW> See this version that works "C++" unchanged.

No it does not, see below.

CW> class item;
CW> typedef map< int , item*, less< int> > collection;

CW> class item {
CW>  public:
CW>  private:
CW>  collection::iterator ithis;

Undefined behavior according to the current standard (17.4.3.6/2):

  In particular, the effects are undefined in the following cases:
  <...>
  - if an incomplete type (3.9) is used as a template argument
    when instantiating a template component.

--
Pavel

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: c.r.wood@gte.net.no_spam ("Charles Wood")
Date: Tue, 4 Mar 2003 19:49:42 +0000 (UTC)
Raw View
""Pavel Kuznetsov"" <pavel@despammed.com> wrote in message
news:b426p5$1relvj$1@ID-97366.news.dfncis.de...
: Charles Wood (c.r.wood@gte.net.no_spam) wrote:
:
: CW> See this version that works "C++" unchanged.
:
: No it does not, see below.
:
: CW> class item;
: CW> typedef map< int , item*, less< int> > collection;
:
: CW> class item {
: CW>  public:
: CW>  private:
: CW>  collection::iterator ithis;

   How is that incomplete?

    map< int, item * /*Pointer to an item*/,less<int> > collection;

:
: Undefined behavior according to the current standard (17.4.3.6/2):
:
:   In particular, the effects are undefined in the following cases:
:   <...>
:   - if an incomplete type (3.9) is used as a template argument
:     when instantiating a template component.
:
: --
: Pavel
:
: ---
: [ 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    ]
: [              --- Please see the FAQ before posting. ---               ]
: [ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]
:

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]