Topic: Can STL vectors handle pointers?


Author: gglass@objectSpace.com (Graham Glass)
Date: 1995/08/07
Raw View
In article <3v36qp$3n6@metro.ucc.su.OZ.AU>, maxtal@Physics.usyd.edu.au (John Max Skaller) says:
>
>In article <3u1jtg$cag@keystone.intergate.net>,
>Benjamin Scherrey <scherrey@proteus-tech.com> wrote:
>>
>>//  destroy() and construct() have to be explicitly defined here as
>>//  the pointer types do not template well for user-defined classes.
>>//
>>//  Is there any way around this?!?!?

>        No. It is only a problem because compilers do not yet
>correctly implement

>        template<class T> void destroy(T *t) {
>                t->~T(); // stuffs up many compilers

YES,there is a way around this, and it's called STL<ToolKit>. This is
the ObjectSpace implementation of STL, and it contains workarounds for
pretty much all of the major compiler limitations. For more information
send email to info@objectspace.com. STL<ToolKit> includes a set of
cross-platform thread & synchronization classes for multi-thread STL
development, as well as a set of helper algorithms that make STL easier
to use.

- Graham





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/07/25
Raw View
In article <3u1jtg$cag@keystone.intergate.net>,
Benjamin Scherrey <scherrey@proteus-tech.com> wrote:
>
>#include "stl.h"        // HP STL Library Headers
>#include "delete.hpp"   // DeleteHole Class
>
>//
>//  destroy() and construct() have to be explicitly defined here as
>//  the pointer types do not template well for user-defined classes.
>//
>//  Is there any way around this?!?!?

 No. It is only a problem because compilers do not yet
correctly implement

 template<class T> void destroy(T *t) {
  t->~T(); // stuffs up many compilers
 }

The solution is to HASSLE your compiler vendor to fix their
compiler for the next release.

The correct operation of STL relies on a full implementation of the
C++ language, including:

 member templates
 partial specialisation
 template function overloading
 destructor and constructor syntax for all types (incl pointers)
 not instantiating unused member functions
 "Koenig" operator lookup in namespaces

Some of these deficiencies can be worked around by modifying
the STL header files as required and some by local overloading.
Some cannot be worked around at all.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: bglenden@colobus.aoc (Brian Glendenning)
Date: 1995/07/20
Raw View
Another interesting case is complex numbers. It will be pretty
disappointing if vector<complex<float>> does not work (cf. the
"valarray vs stl" questions I am asking elsewhere in this group.

Brian
--
        Brian Glendenning - National Radio Astronomy Observatory
bglenden@nrao.edu              Socorro NM               (505) 835-7347





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/07/19
Raw View
In article <KANZE.95Jul18184522@slsvhdt.lts.sel.alcatel.de>,
James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> wrote:
>In article <3tsp4u$b1o@metro.ucc.su.OZ.AU> maxtal@Physics.usyd.edu.au
>(John Max Skaller) writes:
>
>|>  I think I'm missing something. NO PORTABLE VERSION OF STL can support
>|> all operations on pointers. This is because the C++ language requirements
>|> do not require implementors to provide a total ordering on pointers
>|> via operator <.
>
>Except that when storing pointers, the ordering/equality relationship
>that your interested in rarely has anything to do with the pointers
>directly, and everything to do with the object pointed to.  So you are
>almost always required to provide your own `less' function, which
>dereferences the pointers to access these objects.

 I beg to differ. "Objects" themselves are almost never
comparable, not even for equality.  What do two "equal" dialog
boxes in a GUI environment mean?

 One is often NOT interested in comparing objects
for "equality" of value. One is interested in whether
two objects are the identical object-- i.e. the same object at the
same address. That is, in Object Oriented programming it is
the object identity which is fundamental, and it is the
_existence_ of an ordering of that which represents the objects --
not their values -=- which is important to permit sequential processing.

 Often we desire to enumerate all the members of some
container, and STL is based on this notion. Often it does not
matter which order is used, as long as it we get all the
elements. STL has to implement this and so _some_ ordering
is necessary.

 There is no easy way to specify an ordering on pointers.
It is not clear, for example, that a comparison of the
array of unsigned chars constituting the storage of the pointer
will do. This would fail for sure using mixed model 8086
real mode programs, where there is more than one representation
of the same pointer. It might also fail in 80486 protected
mode programs comparing const and non-const pointers if
two selectors (and possibly two descriptors) were used to
address the same linear memory.

 In both these cases equality (==) is REQUIRED to work.
In both these cases less is REQUIRED to work if the pointers denote
positions in the same array.  This will almost never be the case
when one has a container of pointers, as in a sequence of nodes
of a tree structure, or a set of open dialog boxes.

 It is quite true that the programmer can supply
a comparator that works here (assuming one exists). But such
comparators tend to be defaulted in STL. To aid in portability
I have suggested requiring

 less<T*> // all T

be specialised BY THE IMPLEMENTOR so that in fact it does yield
a total order. This places no burden on

 t1 < t2

which can continue to fail. But it is required whenever explicitly
used for this purpose by programmers or defaulted by STL.


--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/07/18
Raw View
In article <3tsp4u$b1o@metro.ucc.su.OZ.AU> maxtal@Physics.usyd.edu.au
(John Max Skaller) writes:

|> In article <3tkutu$q34@sparco.objectSpace.com>,
|> Graham Glass <gglass@objectSpace.com> wrote:
|> >In article <3sspfv$j3i@darkstar.UCSC.EDU>, ray@cse.ucsc.edu (Ray Swartz) says:
|> >>
|> >>I have a class hierarchy that looks like this:
|> >..........
|> >>I got an error inside one of the STL component libraries.
|> >>
|> >>Is it possible to put pointers into an STL container?
|> >>
|> >>Ray Swartz
|> >
|> >As far as I know, the ObjectSpace STL<ToolKit> is the only STL that
|> >allows pointers to objects to be reliably stored without compiler
|> >problems across platforms. The problem you're experiencing is probably
|> >due to a public domain version of STL or a derivative (such as STL++)
|> >that does not accomodate compiler weaknesses.

|>  I think I'm missing something. NO PORTABLE VERSION OF STL can support
|> all operations on pointers. This is because the C++ language requirements
|> do not require implementors to provide a total ordering on pointers
|> via operator <.

Except that when storing pointers, the ordering/equality relationship
that your interested in rarely has anything to do with the pointers
directly, and everything to do with the object pointed to.  So you are
almost always required to provide your own `less' function, which
dereferences the pointers to access these objects.

I do not see where this should automatically introduce any portability
problems.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/07/11
Raw View
In article <3tkutu$q34@sparco.objectSpace.com>,
Graham Glass <gglass@objectSpace.com> wrote:
>In article <3sspfv$j3i@darkstar.UCSC.EDU>, ray@cse.ucsc.edu (Ray Swartz) says:
>>
>>I have a class hierarchy that looks like this:
>..........
>>I got an error inside one of the STL component libraries.
>>
>>Is it possible to put pointers into an STL container?
>>
>>Ray Swartz
>
>As far as I know, the ObjectSpace STL<ToolKit> is the only STL that
>allows pointers to objects to be reliably stored without compiler
>problems across platforms. The problem you're experiencing is probably
>due to a public domain version of STL or a derivative (such as STL++)
>that does not accomodate compiler weaknesses.

 I think I'm missing something. NO PORTABLE VERSION OF STL can support
all operations on pointers. This is because the C++ language requirements
do not require implementors to provide a total ordering on pointers
via operator <.

 I recently proposed "fixing" this without changing the
core language by adding a requirement that

 less<T*>

be required to provide such an order -- perhaps by introduction of
a partial specialisation. Such a change would mean that where comparators
can be supplied there exists one that will work for pointers.

 At present a comparison on a segmented architecture is likely
to produce incorrect results and may result in some STL algorithms
looping forever.

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: gglass@objectSpace.com (Graham Glass)
Date: 1995/07/08
Raw View
In article <3suf1f$7n@steel.interlog.com>, herbs@interlog.com (Herb Sutter) says:
>
>In article <3sspfv$j3i@darkstar.UCSC.EDU>,
...
>>I got an error inside one of the STL component libraries.
>>
>>Thus, my question:
>>Is it possible to put pointers into an STL container?
>
>Yes, but not bald pointers.  (BTW, this is more a language question, so
>I'm crossposting to comp.lang.c++; followups probably should continue there.)

FYI: The ObjectSpace implementation of STL, STL<ToolKit>, can contain
any kinds of pointers and does not have the limitation of STL++.

- Graham Glass

send email to info@objectspace.com for more information





Author: gglass@objectSpace.com (Graham Glass)
Date: 1995/07/08
Raw View
In article <3sspfv$j3i@darkstar.UCSC.EDU>, ray@cse.ucsc.edu (Ray Swartz) says:
>
>I have a class hierarchy that looks like this:
..........
>I got an error inside one of the STL component libraries.
>
>Is it possible to put pointers into an STL container?
>
>Ray Swartz

As far as I know, the ObjectSpace STL<ToolKit> is the only STL that
allows pointers to objects to be reliably stored without compiler
problems across platforms. The problem you're experiencing is probably
due to a public domain version of STL or a derivative (such as STL++)
that does not accomodate compiler weaknesses.

- Graham Glass

send email to info@objectspace.com for more information





Author: khan@xraylith.wisc.edu (Mumit Khan)
Date: 1995/07/08
Raw View
In article <3tkutu$q34@sparco.objectspace.com>,
Graham Glass <gglass@objectSpace.com> wrote:
>
>As far as I know, the ObjectSpace STL<ToolKit> is the only STL that
>allows pointers to objects to be reliably stored without compiler
>problems across platforms. The problem you're experiencing is probably
>due to a public domain version of STL or a derivative (such as STL++)
>that does not accomodate compiler weaknesses.
>
>- Graham Glass

Hmmm ... looks suspiciously like an ad to me :-)

There is nothing complicated/special about storing pointers in STL
containers in any of the implementations I've seen/used so far, just
that some compilers need some more help than others. Even the libg++
STL supports it just fine, and I can use it across more platforms than
I care to name here. I have some examples of it in my STL newbie guide*.
Most of the confusion comes from two issues/misunderstandings:

    - comparator functions need to compare objects, not just the pointer
    values

    - the destroy and construct may need to be overloaded in some cases.

cheers
mumit

* http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html
1





Author: khan@xraylith.wisc.edu (Mumit Khan)
Date: 1995/06/29
Raw View
In article <3sspfv$j3i@darkstar.ucsc.edu>, Ray Swartz <ray@cse.ucsc.edu> wrote:
>
>Is it possible to put pointers into an STL container?
>
>Ray Swartz


Yes, but some implementations seem to handle it a bit differently. You can
proceed two ways:

    - store the pointers as you'd like, but might have to overload
      construct() and destroy() appropriately (at least for HP STL
      using Borland C++).

    - use a wrapper class. This seems to be more platform/implementation
      independent.

There are examples of both ways in
    http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html

btw, it helps if you include your compiler/STL/platform info.

regards
mumit -- khan@xraylith.wisc.edu

Cc: Ray Swartz <ray@cse.ucsc.edu>





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/06/30
Raw View
In article <3suf1f$7n@steel.interlog.com>,
Herb Sutter <herbs@interlog.com> wrote:
>
>Yes, but not bald pointers.  (BTW, this is more a language question, so
>I'm crossposting to comp.lang.c++; followups probably should continue there.)
>
>defalloc.h's destroy() is templated <class T>, takes a T* pointer,
>and invokes pointer->~T() -- and of course passing it a base** fails
>because that's not a pointer to a structure.

 pointer->~T()

is guarranteed to work for ALL types. A change from the ARM.
EG:

 typedef char *charp;
 char ch;
 (&ch)->~charp();

This is well defined --it destroys the char "ch" (which is
usually a nop).

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: ray@cse.ucsc.edu (Ray Swartz)
Date: 1995/06/28
Raw View
I have a class hierarchy that looks like this:

class base {
  // left out
};

class derived1 : public base { ...};

class derived2 : public base { ... };


I want to create a vector of base *s that will be made
into derived1 and derived2 objects using new after I know which
one I want to use (at runtime).

When I tried to do this

vector <base *> x;

I got an error inside one of the STL component libraries.

Thus, my question:

Is it possible to put pointers into an STL container?

Ray Swartz





Author: herbs@interlog.com (Herb Sutter)
Date: 1995/06/29
Raw View
In article <3sspfv$j3i@darkstar.UCSC.EDU>,
   ray@cse.ucsc.edu (Ray Swartz) wrote:
>class base {
>  // left out
>};
>class derived1 : public base { ...};
>class derived2 : public base { ... };
<snip>
>vector <base *> x;
>
>I got an error inside one of the STL component libraries.
>
>Thus, my question:
>Is it possible to put pointers into an STL container?

Yes, but not bald pointers.  (BTW, this is more a language question, so
I'm crossposting to comp.lang.c++; followups probably should continue there.)

defalloc.h's destroy() is templated <class T>, takes a T* pointer,
and invokes pointer->~T() -- and of course passing it a base** fails
because that's not a pointer to a structure.  Typedef'ing base* PBase,
for example, won't solve your problem, because PBase still won't be a
real class with a dtor.

However, note what the problem is: STL has to be able to call the dtor.
That means that you need to give it a class.  You can work around this
pretty easily by encapsulating the pointer in a class and using that.
For example, the following works fine under BC++ 4.5 and Modena's STL++:

#include <iostream.h>
#include <vector.h>

class B             { public: int b;  };
class D1 : public B { public: int d1; };
class D2 : public B { public: int d2; };

class Bptr  // example only; see code at end of article for better version
{
public:
    Bptr::Bptr(B* pB=0) : _pB(pB) {};
    virtual ~Bptr() {}; // in case you want a parallel ptr hierarchy
    B* operator->() { return _pB; };
    operator B*() { return _pB; };  // for convenience, if needed
private:
    B* _pB;
};

int main(int, char**)
{
    Bptr bp = new D1;   // note, not a B specifically
    bp->b = 42;         // assignment through smart ptr

    vector<Bptr> x;
    x.push_back(bp);

    B* bp2 = *x.begin();    // try out the operator B* conversion
    cout << bp2->b << endl; // yes, works fine
    return 0;
}


Of course this is just a quick example; you also want to handle or disallow
the null pointer case, for instance (the reason I allowed the ctor's
argument to default to null is because STL needs your class to have a
default ctor).  I'm including a more useful templatised version below for
your reading pleasure.

Hope this helps,

Herb


//---------- better version ----------
#include <iostream.h>
#include <vector.h>

class B             { public: int b;  };
class D1 : public B { public: int d1; };
class D2 : public B { public: int d2; };

class PtrNull {}; // exception

template <class T>
class Ptr
{ // simple smart pointer class
public:
    Ptr::Ptr(T* pT=0) : _pT(pT) {};

    T* operator->()
    {
        if (!_pT) throw PtrNull();
        return _pT;
    };

    // conversion for convenience, if needed (rarely desired for smart ptrs):
    operator T*()
    {
        if (!_pT) throw PtrNull();
        return _pT;
    };

private:
    T* _pT;
};

int main(int, char**)
{
    try
    {
        Ptr<B> bp = new D1;     // note, it really is a D1, not a B
        bp->b = 42;             // assignment through smart pointer

        vector< Ptr<B> > x;     // vector of pointers is possible
        x.push_back(bp);        // adding a pointer to our vector

        B* bp2 = *x.begin();    // try out the operator B* conversion
        cout << bp2->b << endl; // prints 42

        Ptr<B> bp3;             // note: not pointing to anything!
        cout << bp3->b << endl; // error, causes exception
    }
    catch (PtrNull)
    {
        cout << "*** PtrNull exception caught in main()" << endl;
        // other error processing goes here
    }

    return 0;
}


----- Output is:

42
*** PtrNull exception caught in main()


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Herb Sutter                 2228 Urwin, Ste 102         voice (416) 618-0184
Connected Object Solutions  Oakville ON Canada L6L 2T2    fax (905) 847-6019