Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

auto_ptr conversion derived to base

25 views
Skip to first unread message

perplexing.4...@spamgourmet.com

unread,
Aug 9, 2006, 1:40:19 AM8/9/06
to
Hello,

I get differing results for the following code on differing platforms.
Could someone please advise if what I have written is legal? I found a
reference to an older document that seems to intimate that this might
be ok. (Look right at the end)...
http://www.awprofessional.com/content/images/020163371X/autoptrupdate/auto_ptr_update.html

TIA,

Peter Dulimov.
[email address is my first name followed by the first two letters of my
surname at
resmedA dot comB dot auC, without capitals.]

------------8<-------------------8<-------------------8<-----------------

#include <memory>
#include <iostream>
#include <ostream>
#include <fstream>
#include <iomanip>

class Test
{
std::auto_ptr<std::ostream> m_pOs;

public:
Test(std::auto_ptr<std::ostream> o) : m_pOs(o)
{
*m_pOs << "Hello" << std::endl;
}

private:
Test(const Test& other);
const Test& operator=(const Test& rhs);
};

int main(int argc, char* argv[])
{
Test question(std::auto_ptr<std::ofstream>(new
std::ofstream("file")));

return 0;
}

------------8<-------------------8<-------------------8<-----------------


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Maxim Yegorushkin

unread,
Aug 9, 2006, 8:38:46 AM8/9/06
to

This is a known peculiarity of std::auto_ptr. Derived to base auto_ptr
conversion can only be performed when using direct initialization, but
not copy initialization. As the current language does not provide
r-value references it is simulated in part by auto_ptr and auto_ptr_ref
obscure interaction which is the cause of the inability to convert when
using copy initialization

Function arguments are initialized using copy initialization, this is
why you can not pass a derived auto_ptr to a function expecting a base
one. Consider this code:

#include <memory>

struct A {};
struct B : A {};

int main(int argc, char* argv[])
{

// direct initialization
std::auto_ptr<A> a0(std::auto_ptr<A>(0)); // okay
std::auto_ptr<A> b0(std::auto_ptr<B>(0)); // okay
// copy initialization
std::auto_ptr<A> a1 = std::auto_ptr<A>(0); // okay
std::auto_ptr<A> b1 = std::auto_ptr<B>(0); // error

perplexing.4...@spamgourmet.com

unread,
Aug 9, 2006, 11:34:40 PM8/9/06
to
Maxim Yegorushkin wrote:
> perplexing.4...@spamgourmet.com wrote:
> > Hello,
> >
> > I get differing results for the following code on differing platforms.
> > Could someone please advise if what I have written is legal? I found a
> > reference to an older document that seems to intimate that this might
> > be ok. (Look right at the end)...
> >
>
http://www.awprofessional.com/content/images/020163371X/autoptrupdate/auto_p
> tr_update.html
> >
> > TIA,
> >
> > Peter Dulimov.
> > [email address is my first name followed by the first two letters of my
> > surname at
> > resmedA dot comB dot auC, without capitals.]
> >
>
> ------------8<-------------------8<-------------------8<-----------------
> > [snip]

>
> ------------8<-------------------8<-------------------8<-----------------
>
> This is a known peculiarity of std::auto_ptr. Derived to base auto_ptr
> conversion can only be performed when using direct initialization, but
> not copy initialization. As the current language does not provide
> r-value references it is simulated in part by auto_ptr and auto_ptr_ref
> obscure interaction which is the cause of the inability to convert when
> using copy initialization
>
> Function arguments are initialized using copy initialization, this is
> why you can not pass a derived auto_ptr to a function expecting a base
> one. Consider this code:
>
> #include <memory>
>
> struct A {};
> struct B : A {};
>
> int main(int argc, char* argv[])
> {
> // direct initialization
> std::auto_ptr<A> a0(std::auto_ptr<A>(0)); // okay
> std::auto_ptr<A> b0(std::auto_ptr<B>(0)); // okay
> // copy initialization
> std::auto_ptr<A> a1 = std::auto_ptr<A>(0); // okay
> std::auto_ptr<A> b1 = std::auto_ptr<B>(0); // error
> }
>

Thanks Maxim,

Out of historical curiosity, what happened to the document in the link?
Especially the bit at the end:

[Quote]


Doc. No.: J16/97-0090R1=WG21/N1128R1
Date: November 14, 1997
Project: Programming Language C++
Reply to: Bill Gibbons <bi...@XXXXXXX.org>
Greg Colvin <gr...@XXXXXXX.com>

Fixing auto_ptr.

[snip large amount of document]

(4) Copy-initialization, base-from-derived, e.g.


struct Base {};
struct Derived : Base {};

auto_ptr<Derived> source();
void sink( auto_ptr<Base> );

main() {
sink( source() );
}

This case is not similar to (2), because the sentence quoted
above from 8.5/14 does not apply. So there must be a conversion
function (operator or constructor) from the argument type to the
parameter type, and it will be used to initialize a temporary
variable. Note that this initialization process does not
involve use of a copy constructor:

The user-defined conversion so selected is called to convert the
initializer expression into a temporary, whose type is the type
returned by the call of the user-defined conversion function,
with the cv-qualifiers of the destination type.

The parameter type is auto_ptr<Base>, so there must be a
conversion from auto_ptr<Derived> to auto_ptr<Base>. The
constructor

auto_ptr<Base>::auto_ptr<Derived>(auto_ptr<Derived> &)


does not work because the argument is an rvalue. But the
conversion function


auto_ptr<Derived>::operator auto_ptr<Base>()

does work. The result of calling this conversion function is a
temporary - no copy constructor is needed.

Once the temporary has been created, the draft says:


The object being initialized is then direct-initialized from
the temporary according to the rules above.

This direct-initialization is case (1) which works.

At no time in any of these four cases is the implementation
allowed to make an unnecessary copy of an auto_ptr object.
Therefore it does not matter that the copy constructor does not
work on rvalues.
[End Quote]

Maxim Yegorushkin

unread,
Aug 10, 2006, 10:06:40 AM8/10/06
to

perplexing.4...@spamgourmet.com wrote:

[]

> Out of historical curiosity, what happened to the document in the link?
> Especially the bit at the end:

> Doc. No.: J16/97-0090R1=WG21/N1128R1


> Date: November 14, 1997
> Project: Programming Language C++
> Reply to: Bill Gibbons <bi...@XXXXXXX.org>
> Greg Colvin <gr...@XXXXXXX.com>

[]

I have no clue. Notes
http://www.kangaroologic.com/move_ptr/libs/move_ptr/doc/home.html#note_3
may shed some light on this.

0 new messages