Topic: auto_ptr in the FDIS


Author: Bjorn Fahller <bjorn@algonet.se>
Date: 1998/05/22
Raw View
David Abrahams wrote:

> 1. auto_ptr<T>'s copy constructor has a non-const rhs
> 2. you're not allowed to pass a non-const reference to a temporary

...

> That's where auto_ptr_ref comes in.

> As I understand it, the result of
> foo() is a temporary of type auto_ptr<X>. A conversion operator from
> auto_ptr<X> to auto_ptr<X>::auto_ptr_ref<X> (yes, it's a nested
> template class!) is found by the compiler and applied to the
> temporary.

True, but in the FDIS, the conversion operator to auto_ptr_ref is also
non-const, so it should not be legal to execute that one on a temporaryeither,
or am I wrong in interpreting what's allowed and what's not fortemporaries?
    _
/Bjorn.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/05/23
Raw View
Bjorn Fahller wrote:
>
> David Abrahams wrote:
>
> > 1. auto_ptr<T>'s copy constructor has a non-const rhs
> > 2. you're not allowed to pass a non-const reference to a temporary
>
> ...
>
> > That's where auto_ptr_ref comes in.
>
> > As I understand it, the result of
> > foo() is a temporary of type auto_ptr<X>. A conversion operator from
> > auto_ptr<X> to auto_ptr<X>::auto_ptr_ref<X> (yes, it's a nested
> > template class!) is found by the compiler and applied to the
> > temporary.
>
> True, but in the FDIS, the conversion operator to auto_ptr_ref is also
> non-const, so it should not be legal to execute that one on a temporaryeither,
> or am I wrong in interpreting what's allowed and what's not fortemporaries?

Since the conversion operator is a member function, I don't see
a problem here. You can do the following without problem:

struct X
{
  void foo(); // not const
}

X f();

int main()
{
  f().foo();
}
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Bjorn Fahller <bjorn@algonet.se>
Date: 1998/05/21
Raw View
Hello,

For users of the 3.01 adapted SGI STL, there are (to my knowledge) two
deviations from the FDIS in it. One is a stupid bug, which will be solved
very soon indeed (you can easily do it yourself), in that the "reset" member
function is private while it should of course be public. The other deviation
is a deliberate omission of everything regarding the auto_ptr_ref<T> type,
since I fail to understand it.

Could someone with knowledge of the auto_ptr_ref<T> type tell me what it's
supposed to do, how it's supposed to work and how it's supposed to be used?
   _
/Bjorn.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: abrahams@motu.com (David Abrahams)
Date: 1998/05/21
Raw View
On 21 May 98 13:30:10 GMT, Bjorn Fahller <bjorn@algonet.se> wrote:

>Hello,
>
>For users of the 3.01 adapted SGI STL, there are (to my knowledge) two
>deviations from the FDIS in it. One is a stupid bug, which will be solved
>very soon indeed (you can easily do it yourself), in that the "reset" member
>function is private while it should of course be public. The other deviation
>is a deliberate omission of everything regarding the auto_ptr_ref<T> type,
>since I fail to understand it.
>
>Could someone with knowledge of the auto_ptr_ref<T> type tell me what it's
>supposed to do, how it's supposed to work and how it's supposed to be used?

Ah, auto_ptr_ref. That is a seriously tricky piece of business.
Basically the problem is as follows:

1. auto_ptr<T>'s copy constructor has a non-const rhs
2. you're not allowed to pass a non-const reference to a temporary

Thus, you'll need some help if you want the following to compile:

auto_ptr<X> foo();
void test()
{
  auto_ptr<X> x( foo() );
}

That's where auto_ptr_ref comes in. As I understand it, the result of
foo() is a temporary of type auto_ptr<X>. A conversion operator from
auto_ptr<X> to auto_ptr<X>::auto_ptr_ref<X> (yes, it's a nested
template class!) is found by the compiler and applied to the
temporary. The rules about lifetime of temporaries state that they
exist as long as the full expression that contains them is still being
evaluated, so the auto_ptr<> is still there. The auto_ptr_ref refers
to it. Now the local variable is constructed using the auto_ptr<>
constructor which takes an auto_ptr_ref<> rhs.

This solution was presented to the library working group at the C++
committee meeting in Morristown by a member of the core language
group. I recall that he referred to a very subtle process involving
overload resolution that goes into effect in this particular case, but
unfortunately I don't have an accurate model of the compiler in my
brain, so I couldn't follow it ;). Perhaps someone that does can fill
in the gaps.

-Dave

P.S. Why, you may ask, does auto_ptr<> have a non-const rhs? Aside
from being accurate (the rhs relinquishes ownership), this was done to
prevent you from using an auto_ptr in a container. All practical
container implementations take a const T& argument to their
single-element insert functions, and similar restrictions in common
implementations of other member functions would prevent _any_ use of a
raw auto_ptr as a contained element.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: abrahams@motu.com (David Abrahams)
Date: 1998/05/19
Raw View
On 11 May 1998 06:53:45 GMT, John Lacey <johnl@vizdom.com> wrote:

>David Goh wrote:
>>
>> In comp.std.c++, on 07 May 98 11:14:43 GMT
>> John Lacey <johnl@vizdom.com> wrote:
>> >In reading the code for STLport [3.01], I found that the copy
>> >constructor and assignment operator take non-const auto_ptrs.
>> >Together with the removal of reset and no assignment operator
>> >taking a pointer, [...].
>>
>> Urm.  As far as I can tell, you must be reading the CD2 auto_ptr<>.
>
>No, the latest STLport release claims an FDIS-compliant
>implementation of auto_ptr, which is what raised the questions. I
>am familiar with the reversal of auto_ptr's semantics back to the
>pre-CD2 version.

Unfortunately, that claim is a mistake. The FDIS auto-ptr is
substantially different. I expect the next STLPort release to correct
that problem, though.

>> Umm..  Guru of the Week #25:  auto_ptr (Special Edition)
>> contains *lots* of info on the situation re auto_ptr<>.
>
>It's at http://www.peerdirect.com/resources/gotw.html, and it
>contains some information. It doesn't mention reset or release,
>however, though it does say that the following *is* illegal:
>
>> >       ap = auto_ptr<T>(new T); // can't do this, either
>
>You can't pass a temporary through a non-const reference. This is
>nice, in that given the semantics of auto_ptr you still know it's
>safe to pass them as auto_ptr<T> const &. What was puzzling me
>was the absence of reset, which is after all just a bug in
>STLport.

The FDIS copy constructors and assignment operators all have non-const
rhs, and there are some additional very clever tricks to make it
possible to pass an auto_ptr as a return value. The above line should
compile with an FDIS auto_ptr and a conforming compiler.

Incidentally, I recommend AGAINST ever passing auto_ptr by reference.
It's legal, but you can always pass a reference to the object it
refers to instead. If you only pass auto_ptr by value, you are assured
that when you see auto_ptr in your code, it signifies ownership.

-Dave
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/05/11
Raw View
Edward Diener <eddielee@abraxis.com> writes:

> auto_ptr<T> ap(new T);
> ap = auto_ptr<T>(new T);

> If this is not allowable in FDIS, I would like to know why.

Because you can't bind a temporary to a non-const
reference. [over.ics.ref]:

 A standard conversion sequence cannot be formed if it requires binding
  a reference to non-const to an rvalue (except when binding an implicit
  object  parameter;  see  the  special   rules   for   that   case   in
  _over.match.funcs_).  [Note: this means, for example, that a candidate
  function  cannot  be a viable function if it has a non-const reference
  parameter (other than the implicit object parameter)  and  the  corre-
  sponding argument is a temporary or would require one to be created to
  initialize the reference (see _dcl.init.ref_).  ]

Several compilers accept this as an extension, but they're required to
emit a diagnostic.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: John Lacey <johnl@vizdom.com>
Date: 1998/05/11
Raw View
David Goh wrote:
>
> In comp.std.c++, on 07 May 98 11:14:43 GMT
> John Lacey <johnl@vizdom.com> wrote:
> >In reading the code for STLport [3.01], I found that the copy
> >constructor and assignment operator take non-const auto_ptrs.
> >Together with the removal of reset and no assignment operator
> >taking a pointer, [...].
>
> Urm.  As far as I can tell, you must be reading the CD2 auto_ptr<>.

No, the latest STLport release claims an FDIS-compliant
implementation of auto_ptr, which is what raised the questions. I
am familiar with the reversal of auto_ptr's semantics back to the
pre-CD2 version.

> Umm..  Guru of the Week #25:  auto_ptr (Special Edition)
> contains *lots* of info on the situation re auto_ptr<>.

It's at http://www.peerdirect.com/resources/gotw.html, and it
contains some information. It doesn't mention reset or release,
however, though it does say that the following *is* illegal:

> >       ap = auto_ptr<T>(new T); // can't do this, either

You can't pass a temporary through a non-const reference. This is
nice, in that given the semantics of auto_ptr you still know it's
safe to pass them as auto_ptr<T> const &. What was puzzling me
was the absence of reset, which is after all just a bug in
STLport.

John L


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Glen Wilcox" <GDW80116@aol.com>
Date: 1998/05/11
Raw View
> auto_ptr<T> ap(new T); // let's start with this
> ap = new T; // can't do this

Your compiler supports the keyword explicit. You are attempting to invoke
the auto_ptr cctor which needs a &auto_ptr. The auto_ptr ctor is declared
explicit so it does not allow the implicit coversion of new T to
auto_ptr<T>.

> ap = auto_ptr<T>(new T); // can't do this, either
I think this may be a compiler bug. Visual C++ 5.0 and the SGI ver7.2
compilers support this. You might check the implementation of the auto_ptr
cctor to see if it accepts const auto_ptr<T> & or simply auto_ptr<T>&(this
would be a problem).

> ap.reset(new T); // or this
My copy of the Standard doesn't contain a reset function.
>
> auto_ptr<T> new_ap(new T);
> ap = new_ap; // have to do this
>
Ugly but it should work appropriately.


Glen



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Edward Diener <eddielee@abraxis.com>
Date: 1998/05/14
Raw View
I realized this after I sent the message but I then looked at the BCB3 (
actually Rogue Wave ) implementation of auto_ptr and noticed that it takes a
const auto_ptr<T> & in its constructor. That would explain why it works for
me but I don't know if that is compliant to the FDIS and the upcoming
standard.

Alexandre Oliva wrote:

> Edward Diener <eddielee@abraxis.com> writes:
>
> > auto_ptr<T> ap(new T);
> > ap = auto_ptr<T>(new T);
>
> > If this is not allowable in FDIS, I would like to know why.
>
> Because you can't bind a temporary to a non-const
> reference. [over.ics.ref]:
>
>  A standard conversion sequence cannot be formed if it requires binding
>   a reference to non-const to an rvalue (except when binding an implicit
>   object  parameter;  see  the  special   rules   for   that   case   in
>   _over.match.funcs_).  [Note: this means, for example, that a candidate
>   function  cannot  be a viable function if it has a non-const reference
>   parameter (other than the implicit object parameter)  and  the  corre-
>   sponding argument is a temporary or would require one to be created to
>   initialize the reference (see _dcl.init.ref_).  ]
>
> Several compilers accept this as an extension, but they're required to
> emit a diagnostic.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/05/17
Raw View
Edward Diener <eddielee@abraxis.com> writes:

> I [...] noticed that it takes a const auto_ptr<T> & in its
> constructor. That would explain why it works for me but I don't know
> if that is compliant to the FDIS and the upcoming standard.

It is not.  In the FDIS, auto_ptr's constructor takes a non-const
auto_ptr&, because the passed auto_ptr is modified.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: John Lacey <johnl@vizdom.com>
Date: 1998/05/07
Raw View
In reading the code for STLport, I found that the copy
constructor and assignment operator take non-const auto_ptrs.
Together with the removal of reset and no assignment operator
taking a pointer, this makes my own uses of auto_ptrs more
difficult. To reassign them I have to declare a new auto_ptr
initialized with the new pointer value, and then assign that to
my existing auto_ptr.

 auto_ptr<T> ap(new T); // let's start with this

 ap = new T; // can't do this
 ap = auto_ptr<T>(new T); // can't do this, either
 ap.reset(new T); // or this

 auto_ptr<T> new_ap(new T);
 ap = new_ap; // have to do this

Is this really true?

John L
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: david@unico.com.au (David Goh)
Date: 1998/05/08
Raw View
In comp.std.c++, on 07 May 98 11:14:43 GMT
John Lacey <johnl@vizdom.com> wrote:
>In reading the code for STLport, I found that the copy
>constructor and assignment operator take non-const auto_ptrs.
>Together with the removal of reset and no assignment operator
>taking a pointer, this makes my own uses of auto_ptrs more
>difficult. To reassign them I have to declare a new auto_ptr
>initialized with the new pointer value, and then assign that to
>my existing auto_ptr.

Urm.  As far as I can tell, you must be reading the CD2 auto_ptr<>.
That's no longer the definition supported by the nearly final standard.

auto_ptr copy constructor *still* takes a non-const auto_ptr, but reset
is back.  There is no ownership flag, and copying an auto_ptr means that
the auto_ptr copied *from* becomes null.

Note, too, that storing auto_ptr<>s in STL containers is *NOT*
a safe thing to do, because copies are not equivalent.  STL
implementations, IIRC, are allowed to assume that they are...

Umm..  Guru of the Week #25:  auto_ptr (Special Edition) (The old site
for them is http://www.cntc.com, but I *think* it's been revamped and
moved...  Try there and see what happens) contains *lots* of info on
the situation re auto_ptr<>.

> auto_ptr<T> ap(new T); // let's start with this

Yeps, that's fine.

> ap = new T; // can't do this

Yeps.  Assigning a raw pointer is bogus usage.  You want the
programmer to clearly show they know that they're assigning a new
object.

> ap = auto_ptr<T>(new T); // can't do this, either

That *should* work, I think... It's not very *useful*, but it should
work.  That temporary is *not* const, so it be fine.

Of course, it's sort of wasteful, since reset() is the correct thing to
do... so it really shouldn't be used anyway.

> ap.reset(new T); // or this

That should be fine as per the final draft.

> auto_ptr<T> new_ap(new T);
> ap = new_ap; // have to do this

Nup.  reset() is back.  This is a good thing.

>Is this really true?

In a word, no.

Later,

   David

--
| david@unico.com.au (David Goh, Unico Computer Systems, +61-3-9866-5688)
Accuracy, n.:
        The vice of being right


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "greg" <yo@mama.com>
Date: 1998/05/08
Raw View


John Lacey <johnl@vizdom.com> wrote in article
<35514818.49712C96@vizdom.com>...
> In reading the code for STLport, I found that the copy
> constructor and assignment operator take non-const auto_ptrs.
> Together with the removal of reset and no assignment operator
> taking a pointer, this makes my own uses of auto_ptrs more
> difficult. To reassign them I have to declare a new auto_ptr
> initialized with the new pointer value, and then assign that to
> my existing auto_ptr.
>
>  auto_ptr<T> ap(new T); // let's start with this
>

OK.

>  ap = new T; // can't do this

No implicit construction or assignment of T* to auto_ptr<T>.

>  ap = auto_ptr<T>(new T); // can't do this, either

Should work.

>  ap.reset(new T); // or this

Should work.

>  auto_ptr<T> new_ap(new T);
>  ap = new_ap; // have to do this

Also should work.

> Is this really true?

It would appear that you have a non-conforming implementation.  Here is a
one that I think conforms:

////////////////////////////////////////////////////////////////////////////
////
template<typename X> struct auto_ptr {
   template <typename Y> struct auto_ptr_ref {
      Y* py;
      auto_ptr_ref(Y* p) : py(p) {}
   };
   X* px;
public:
   typedef X element_type;

   explicit auto_ptr(X* p =0) throw() : px(p) {}
   auto_ptr(auto_ptr& r) throw() : px(r.release()) {}
   template<typename Y> auto_ptr(auto_ptr<Y>& r) throw() : px(r.release())
{}

   auto_ptr& operator=(auto_ptr& r) throw() {
      reset(r.release());
      return *this;
   }
   template<typename Y> auto_ptr& operator=(auto_ptr<Y>& r) throw() {
      reset(r.release());
      return *this;
   }

   ~auto_ptr() { delete px; }

   X& operator*() const throw() { return *px; }
   X* operator->() const throw() { return px; }
   X* get() const throw() { return px; }
   X* release() throw() { X* p=px; px=0; return p; }
   void reset(X* p=0) throw() { if (px != p) delete px, px = p; }

   auto_ptr(auto_ptr_ref<X> r) throw() : px(r.py) {}
   template<typename Y> operator auto_ptr_ref<Y>() throw() {
      return auto_ptr_ref<Y>(release());
   }
   template<typename Y> operator auto_ptr<Y>() throw() {
      return auto_ptr<Y>(release());
   }
};


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Edward Diener <eddielee@abraxis.com>
Date: 1998/05/08
Raw View
With my compiler, BCB3, I can have done this:

auto_ptr<T> ap(new T);
ap = auto_ptr<T>(new T);

If this is not allowable in FDIS, I would like to know why.

John Lacey wrote:

> In reading the code for STLport, I found that the copy
> constructor and assignment operator take non-const auto_ptrs.
> Together with the removal of reset and no assignment operator
> taking a pointer, this makes my own uses of auto_ptrs more
> difficult. To reassign them I have to declare a new auto_ptr
> initialized with the new pointer value, and then assign that to
> my existing auto_ptr.
>
>         auto_ptr<T> ap(new T); // let's start with this
>
>         ap = new T; // can't do this
>         ap = auto_ptr<T>(new T); // can't do this, either
>         ap.reset(new T); // or this
>
>         auto_ptr<T> new_ap(new T);
>         ap = new_ap; // have to do this
>
> Is this really true?


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]