[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

A Sample auto_ptr implementation

Ankur Arora

10/13/2008 11:59:00 AM

Hi All,

I'm building a sample application that uses a custom auto_ptr
implementation.
The program crashes with the following output:-

Output (Debug Assertion failed)
----------


release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
aap: ptr3= 10
aap: exiting app
Deleting pointee...10
Deleting pointee...-572662307 (...problem ?)

Code
--------

#include<iostream>

using namespace std;

// MyAutoPtr Interface
template <class T>
class MyAutoPtr
{
public:

explicit MyAutoPtr(T* ptr=0);

~MyAutoPtr();

template <class U>
MyAutoPtr(MyAutoPtr<U> *rhs);

//copy constructor member template, initialize this member pointer
with any other compatible auto_ptr
template <class U>
MyAutoPtr(MyAutoPtr<U>& rhs);

//assignment operator
template <class U>
MyAutoPtr<T>& operator=(MyAutoPtr<U>& rhs);

//relinquish ownership
T* release();

T* get() const;

//reset the auto_ptr, delete pointee, assume ownership of p
void reset(T* ptr=0);

T& operator*() const;
T* operator->() const;


private:

T* pointee;
//template <class U>
//friend class MyAutoPtr<U>;
};

//Implementation

template<typename T>
inline MyAutoPtr<T>::MyAutoPtr(T* ptr):pointee(ptr)
{ }

template <class T>
inline MyAutoPtr<T>::~MyAutoPtr()
{
if(pointee)
{
cout<<"\n\t Deleting pointee..."<<*pointee;
delete pointee;
}
}

template <class T>
template <class U>
inline MyAutoPtr<T>::MyAutoPtr(MyAutoPtr<U>& rhs) :
pointee(rhs.release())
{
cout<<"\n\t copy constructor";
}

template<class T>
template<class U>
MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
{
cout<<"\n\t Inside operator=";
if(this!=&rhs)
{
cout<<"\n\t Inside operator=, calling reset";
reset(rhs.release());
}
return *this;
}

template <class T>
T* MyAutoPtr<T>::get() const
{
return pointee;
}

template <class T>
inline T& MyAutoPtr<T>::operator *() const
{
return *pointee;
}

template<class T>
inline T* MyAutoPtr<T>::operator->() const
{ return pointee; }

template<class T>
T* MyAutoPtr<T>::release()
{
cout<<"\n\t release called";
T* oldp=pointee;
pointee=0;

return oldp;
}

template<class T>
void MyAutoPtr<T>::reset(T* p)
{
cout<<"\n\t reset called";
if(pointee!=p)
{
delete pointee;
//pointee=0;
}

pointee=p;
}

void main()
{
MyAutoPtr<int> intp(new int(10));
MyAutoPtr<int> intp2(intp);
MyAutoPtr<int> intp3(new int(20));

//cout<<"ptr1= "<<*intp;
cout<<"\n\t aap: ptr2= "<<*intp2;
cout<<"\n\t aap: ptr3= "<<*intp3;

intp3 = intp2; //
==============================> 1

cout<<"\n\t aap: ptr3= "<<*intp3;

cout<<"\n\t aap: exiting app";
}



It seems, on debugging, that class's custom operator= is somehow not
been called at 1 and hence a problem while destructing. (since delete
is being called twice on the same pointer)
---------------------------------------------------------------------------------------------------------

Q1. Any problems with the above code ?
Q2. What is causing operator= not to be called and how to fix it ?
Q3. Following statements (in the class interface) cause compiler
errors, if not commented out

private:
T* pointee;
//template <class U>
//friend class MyAutoPtr<U>;

MSDN defines this error as:-

Compiler Error C3772
Error Message
"name" : invalid friend template declaration

It is invalid to declare a friend of a class template specialization.
You cannot declare an explicit or partial specialization of a class
template and in the same statement declare a friend of that
specialization. The name placeholder identifies the invalid
declaration.
To correct this error
-Do not declare a friend of a class template specialization.
-If appropriate for your application, declare a friend of the class
template, or declare a friend of a particular partial or explicit
specialization.

Why such error, if this is not a specialization? or is it a
specialization somehow?
---------------------------------------------------------------------------------------------------------

Any help will be highly appreciated!

Thanks!
21 Answers

Yakov Gerlovin

10/13/2008 12:37:00 PM

0

Try to define assignment operator without template U parameter:

//assignment operator
MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);

Why do you need that 'U' anyway, release should return the pointer to
be passed to reset, so T and U should be equal.

Kai-Uwe Bux

10/13/2008 12:54:00 PM

0

Ankur Arora wrote:

> Hi All,
>
> I'm building a sample application that uses a custom auto_ptr
> implementation.
> The program crashes with the following output:-
>
> Output (Debug Assertion failed)
> ----------
>
>
> release called
> copy constructor
> aap: ptr2= 10
> aap: ptr3= 20
> aap: ptr3= 10
> aap: exiting app
> Deleting pointee...10
> Deleting pointee...-572662307 (...problem ?)
>
> Code
> --------

Just a data point: your code works for me with output

release called
copy constructor
aap: ptr2= 10
aap: ptr3= 20
Inside operator=
Inside operator=, calling reset
release called
reset called
aap: ptr3= 10
aap: exiting app
Deleting pointee...10

So I just have nits:


> #include<iostream>
>
> using namespace std;

It's a bad idea to use using namespace std in a header.



[snip]
> template <class T>
> inline MyAutoPtr<T>::~MyAutoPtr()
> {
> if(pointee)
> {
> cout<<"\n\t Deleting pointee..."<<*pointee;
> delete pointee;
> }
> }

delete will perform its own check for 0. It is required to be a null-op in
that case.


[snip]
> template<class T>
> template<class U>
> MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
> {
> cout<<"\n\t Inside operator=";
> if(this!=&rhs)

This if-clause will not compile when T and U are different.

You could use

if ( this->pointee == rhs.pointee )

instead (I think).

> {
> cout<<"\n\t Inside operator=, calling reset";
> reset(rhs.release());
> }
> return *this;
> }

[snip]
> void main()
[snip]

Main returns int. I get an error with g++ at this point.


> It seems, on debugging, that class's custom operator= is somehow not
> been called at 1 and hence a problem while destructing. (since delete
> is being called twice on the same pointer)
> ---------------------------------------------------------------------------------------------------------
>
> Q1. Any problems with the above code ?

It works with g++.

> Q2. What is causing operator= not to be called and how to fix it ?

A bug in your compiler?


[snip]


Best

Kai-Uwe Bux

Kai-Uwe Bux

10/13/2008 12:59:00 PM

0

Yakov Gerlovin wrote:

> Try to define assignment operator without template U parameter:
>
> //assignment operator
> MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);
>
> Why do you need that 'U' anyway, release should return the pointer to
> be passed to reset, so T and U should be equal.

He needs it to support polymorphism. When D is derived from B, MyAutoPtr<B>
should be constructible and assignable from MyAutoPtr<D>.

But the OP could define copy-constructor and assignment operator from T
separately. For the copy-constructor, I recall that this is needed. I am
not sure if it is needed for the assignment operator.


Best

Kai-Uwe Bux

anon

10/13/2008 1:18:00 PM

0

> [snip]
>> template <class T>
>> inline MyAutoPtr<T>::~MyAutoPtr()
>> {
>> if(pointee)
>> {
>> cout<<"\n\t Deleting pointee..."<<*pointee;
>> delete pointee;
>> }
>> }
>
> delete will perform its own check for 0. It is required to be a null-op in
> that case.
>

Check for 0 is required for printing the debug message. Other then that,
the check should be removed

Ankur Arora

10/13/2008 1:59:00 PM

0

On Oct 13, 2:36 pm, Yakov Gerlovin <yakov.gerlo...@gmail.com> wrote:
> Try to define assignment operator without template U parameter:
>
> //assignment operator
> MyAutoPtr<T>& operator=(MyAutoPtr<T>& rhs);
>
> Why do you need that 'U' anyway, release should return the pointer to
> be passed to reset, so T and U should be equal.

Hi Yakov,

Thanks for the reply!

Yes indeed when I remove the member template function i.e. change the
function as you suggested, it works.
But I don't know whats the problem with the first version.

I should also mention that I'm using visual studio 2008 express
edition.
This be a compiler issue, u reckon?

Thanks!

Ankur Arora

10/13/2008 2:10:00 PM

0

Thanks for the reply Kai!
Please see the comments below.

On Oct 13, 2:53 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Ankur Arora wrote:
> > Hi All,
>
> > I'm building a sample application that uses a custom auto_ptr
> > implementation.
> > The program crashes with the following output:-
>
> > Output               (Debug Assertion failed)
> > ----------
>
> >          release called
> >          copy constructor
> >          aap: ptr2= 10
> >          aap: ptr3= 20
> >          aap: ptr3= 10
> >          aap: exiting app
> >          Deleting pointee...10
> >          Deleting pointee...-572662307         (...problem ?)
>
> > Code
> > --------
>
> Just a data point: your code works for me with output
>
>          release called
>          copy constructor
>          aap: ptr2= 10
>          aap: ptr3= 20
>          Inside operator=
>          Inside operator=, calling reset
>          release called
>          reset called
>          aap: ptr3= 10
>          aap: exiting app
>          Deleting pointee...10
>
> So I just have nits:
>
> > #include<iostream>
>
> > using namespace std;
>
> It's a bad idea to use using namespace std in a header.
>
Agreed!

> [snip]
>
> > template <class T>
> > inline MyAutoPtr<T>::~MyAutoPtr()
> > {
> >   if(pointee)
> >   {
> >     cout<<"\n\t Deleting pointee..."<<*pointee;
> >     delete pointee;
> >    }
> > }
>
> delete will perform its own check for 0. It is required to be a null-op in
> that case.

I did this since removing this check caused the program to crash, even
though I had made pointee equals to 0 in release(), which was used in
the copy constructor.
I'm using visual studio 2008 express edition. You reckon this is a
complier issue?

>
> [snip]
>
> > template<class T>
> > template<class U>
> > MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
> > {
> >   cout<<"\n\t Inside operator=";
> >   if(this!=&rhs)
>
> This if-clause will not compile when T and U are different.
>
> You could use
>
>   if ( this->pointee == rhs.pointee )
>
> instead (I think).
>

I saw this example in "More Effective C++" by scott meyers. This was
how its used in that book. Here is a code.

//Interface
template<class T>
class auto_ptr {
public:
explicit auto_ptr(T *p = 0); // see Item 5 for a
// description of
"explicit"
template<class U> // copy constructor member
auto_ptr(auto_ptr<U>& rhs); // template (see Item 28):
// initialize a new
auto_ptr
// with any compatible
// auto_ptr
~auto_ptr();
template<class U> // assignment operator
auto_ptr<T>& // member template (see
operator=(auto_ptr<U>& rhs); // Item 28): assign from
any
// compatible auto_ptr
T& operator*() const; // see Item 28
T* operator->() const; // see Item 28
T* get() const; // return value of current
// dumb pointer
T* release(); // relinquish ownership of
// current dumb pointer
and
// return its value
void reset(T *p = 0); // delete owned pointer;
// assume ownership of p
private:
T *pointee;
template<class U> // make all auto_ptr
classes
friend class auto_ptr<U>; // friends of one another
};

//Implementation
template<class T>
inline auto_ptr<T>::auto_ptr(T *p)
: pointee(p)
{}
template<class T>
inline auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
: pointee(rhs.release())
{}
template<class T>
inline auto_ptr<T>::~auto_ptr()
{ delete pointee; }
template<class T>
template<class U>
inline auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
{
if (this != &rhs) reset(rhs.release());
return *this;
}
template<class T>
inline T& auto_ptr<T>::operator*() const
{ return *pointee; }
template<class T>
inline T* auto_ptr<T>::operator->() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::get() const
{ return pointee; }
template<class T>
inline T* auto_ptr<T>::release()
{
T *oldPointee = pointee;
pointee = 0;
return oldPointee;
}
template<class T>
inline void auto_ptr<T>::reset(T *p)
{
if (pointee != p) {
delete pointee;
pointee = p;
}
}



Anything wrong with the above ? (would be surprised if there is, as it
came from scott meyers)



> > Q1. Any problems with the above code ?
>
> It works with g++.
>

Again, looks like an issue with visual studio 2008 express.

> > Q2. What is causing operator= not to be called and how to fix it ?
>
> A bug in your compiler?
>
> [snip]
>
> Best
>
> Kai-Uwe Bux

Barry

10/13/2008 3:07:00 PM

0

On Oct 13, 10:10 pm, Ankur Arora <ankuraror...@gmail.com> wrote:
> Thanks for the reply Kai!
> Please see the comments below.
>
> On Oct 13, 2:53 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>
> > Ankur Arora wrote:
> > > Hi All,
>
> > > I'm building a sample application that uses a custom auto_ptr
> > > implementation.
> > > The program crashes with the following output:-
>
> > > Output               (Debug Assertion failed)
> > > ----------
>
> > >          release called
> > >          copy constructor
> > >          aap: ptr2= 10
> > >          aap: ptr3= 20
> > >          aap: ptr3= 10
> > >          aap: exiting app
> > >          Deleting pointee...10
> > >          Deleting pointee...-572662307         (...problem ?)
>
> > > Code
> > > --------
>
> > Just a data point: your code works for me with output
>
> >          release called
> >          copy constructor
> >          aap: ptr2= 10
> >          aap: ptr3= 20
> >          Inside operator=
> >          Inside operator=, calling reset
> >          release called
> >          reset called
> >          aap: ptr3= 10
> >          aap: exiting app
> >          Deleting pointee...10
>
> > So I just have nits:
>
> > > #include<iostream>
>
> > > using namespace std;
>
> > It's a bad idea to use using namespace std in a header.
>
> Agreed!
>
> > [snip]
>
> > > template <class T>
> > > inline MyAutoPtr<T>::~MyAutoPtr()
> > > {
> > >   if(pointee)
> > >   {
> > >     cout<<"\n\t Deleting pointee..."<<*pointee;
> > >     delete pointee;
> > >    }
> > > }
>
> > delete will perform its own check for 0. It is required to be a null-op in
> > that case.
>
> I did this since removing this check caused the program to crash, even
> though I had made pointee equals to 0 in release(), which was used in
> the copy constructor.
> I'm using visual studio 2008 express edition. You reckon this is a
> complier issue?
>
>
>
>
>
> > [snip]
>
> > > template<class T>
> > > template<class U>
> > > MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
> > > {
> > >   cout<<"\n\t Inside operator=";
> > >   if(this!=&rhs)
>
> > This if-clause will not compile when T and U are different.
>
> > You could use
>
> >   if ( this->pointee == rhs.pointee )
>
> > instead (I think).
>
> I saw this example in "More Effective C++" by scott meyers. This was
> how its used in that book. Here is a code.
>
> //Interface
> template<class T>
> class auto_ptr {
> public:
>   explicit auto_ptr(T *p = 0);              // see Item 5 for a
>                                             // description of
> "explicit"
>   template<class U>                         // copy constructor member
>   auto_ptr(auto_ptr<U>& rhs);               // template (see Item 28):
>                                             // initialize a new
> auto_ptr
>                                             // with any compatible
>                                             // auto_ptr
>   ~auto_ptr();
>   template<class U>                         // assignment operator
>   auto_ptr<T>&                              // member template (see
>   operator=(auto_ptr<U>& rhs);              // Item 28): assign from
> any
>                                             // compatible auto_ptr
>   T& operator*() const;                     // see Item 28
>   T* operator->() const;                    // see Item 28
>   T* get() const;                           // return value of current
>                                             // dumb pointer
>   T* release();                             // relinquish ownership of
>                                             // current dumb pointer
> and
>                                             // return its value
>   void reset(T *p = 0);                     // delete owned pointer;
>                                             // assume ownership of p
> private:
>   T *pointee;
> template<class U>                           // make all auto_ptr
> classes
> friend class auto_ptr<U>;                   // friends of one another
>
> };
>
> //Implementation
> template<class T>
> inline auto_ptr<T>::auto_ptr(T *p)
> : pointee(p)
> {}
> template<class T>
>   inline auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
>   : pointee(rhs.release())
>   {}
> template<class T>
> inline auto_ptr<T>::~auto_ptr()
> { delete pointee; }
> template<class T>
>   template<class U>
>   inline auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
>   {
>     if (this != &rhs) reset(rhs.release());
>     return *this;
>   }
> template<class T>
> inline T& auto_ptr<T>::operator*() const
> { return *pointee; }
> template<class T>
> inline T* auto_ptr<T>::operator->() const
> { return pointee; }
> template<class T>
> inline T* auto_ptr<T>::get() const
> { return pointee; }
> template<class T>
> inline T* auto_ptr<T>::release()
> {
>   T *oldPointee = pointee;
>   pointee = 0;
>   return oldPointee;}
>
> template<class T>
> inline void auto_ptr<T>::reset(T *p)
> {
>   if (pointee != p) {
>     delete pointee;
>     pointee = p;
>   }
>
> }
>
> Anything wrong with the above ? (would be surprised if there is, as it
> came from scott meyers)
>
> > > Q1. Any problems with the above code ?

There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
on
this), adding auto_ptr_ref for conversion, which supports rvalue
initialization for auto_ptr. which is done transparently.

void fun(auto_ptr<T> ptr);
fun(auto_ptr(new T)); // rvalue -> auto_ptr_ref -> auto_ptr

>
> > It works with g++.
>
> Again, looks like an issue with visual studio 2008 express.

there are two problem with visual C++ 2005 in this issue:
1. as extension, "explicit" does NOT work as standard says.
needs /Za switch to turn it off.

2. auto_ptr_ref use void* rather T*

point 2 is fixed by VS 2008(none expression version,
but I expression version should ship the same lib)

>
> > > Q2. What is causing operator= not to be called and how to fix it ?
>
> > A bug in your compiler?
>
> > [snip]

--
Best Regards
Barry

Ankur Arora

10/15/2008 7:17:00 AM

0

On Oct 13, 5:06 pm, Barry <dhb2...@gmail.com> wrote:
> On Oct 13, 10:10 pm, Ankur Arora <ankuraror...@gmail.com> wrote:
>
>
>
> > Thanks for the reply Kai!
> > Please see the comments below.
>
> > On Oct 13, 2:53 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>
> > > Ankur Arora wrote:
> > > > Hi All,
>
> > > > I'm building a sample application that uses a custom auto_ptr
> > > > implementation.
> > > > The program crashes with the following output:-
>
> > > > Output               (Debug Assertion failed)
> > > > ----------
>
> > > >          release called
> > > >          copy constructor
> > > >          aap: ptr2= 10
> > > >          aap: ptr3= 20
> > > >          aap: ptr3= 10
> > > >          aap: exiting app
> > > >          Deleting pointee...10
> > > >          Deleting pointee...-572662307         (....problem ?)
>
> > > > Code
> > > > --------
>
> > > Just a data point: your code works for me with output
>
> > >          release called
> > >          copy constructor
> > >          aap: ptr2= 10
> > >          aap: ptr3= 20
> > >          Inside operator=
> > >          Inside operator=, calling reset
> > >          release called
> > >          reset called
> > >          aap: ptr3= 10
> > >          aap: exiting app
> > >          Deleting pointee...10
>
> > > So I just have nits:
>
> > > > #include<iostream>
>
> > > > using namespace std;
>
> > > It's a bad idea to use using namespace std in a header.
>
> > Agreed!
>
> > > [snip]
>
> > > > template <class T>
> > > > inline MyAutoPtr<T>::~MyAutoPtr()
> > > > {
> > > >   if(pointee)
> > > >   {
> > > >     cout<<"\n\t Deleting pointee..."<<*pointee;
> > > >     delete pointee;
> > > >    }
> > > > }
>
> > > delete will perform its own check for 0. It is required to be a null-op in
> > > that case.
>
> > I did this since removing this check caused the program to crash, even
> > though I had made pointee equals to 0 in release(), which was used in
> > the copy constructor.
> > I'm using visual studio 2008 express edition. You reckon this is a
> > complier issue?
>
> > > [snip]
>
> > > > template<class T>
> > > > template<class U>
> > > > MyAutoPtr<T>& MyAutoPtr<T>::operator=(MyAutoPtr<U>& rhs)
> > > > {
> > > >   cout<<"\n\t Inside operator=";
> > > >   if(this!=&rhs)
>
> > > This if-clause will not compile when T and U are different.
>
> > > You could use
>
> > >   if ( this->pointee == rhs.pointee )
>
> > > instead (I think).
>
> > I saw this example in "More Effective C++" by scott meyers. This was
> > how its used in that book. Here is a code.
>
> > //Interface
> > template<class T>
> > class auto_ptr {
> > public:
> >   explicit auto_ptr(T *p = 0);              // see Item 5 for a
> >                                             // description of
> > "explicit"
> >   template<class U>                         // copy constructor member
> >   auto_ptr(auto_ptr<U>& rhs);               // template (see Item 28):
> >                                             // initialize a new
> > auto_ptr
> >                                             // with any compatible
> >                                             // auto_ptr
> >   ~auto_ptr();
> >   template<class U>                         // assignment operator
> >   auto_ptr<T>&                              // member template (see
> >   operator=(auto_ptr<U>& rhs);              // Item 28): assign from
> > any
> >                                             // compatible auto_ptr
> >   T& operator*() const;                     // see Item 28
> >   T* operator->() const;                    // see Item 28
> >   T* get() const;                           // return value of current
> >                                             // dumb pointer
> >   T* release();                             // relinquish ownership of
> >                                             // current dumb pointer
> > and
> >                                             // return its value
> >   void reset(T *p = 0);                     // delete owned pointer;
> >                                             // assume ownership of p
> > private:
> >   T *pointee;
> > template<class U>                           // make all auto_ptr
> > classes
> > friend class auto_ptr<U>;                   // friends of one another
>
> > };
>
> > //Implementation
> > template<class T>
> > inline auto_ptr<T>::auto_ptr(T *p)
> > : pointee(p)
> > {}
> > template<class T>
> >   inline auto_ptr<T>::auto_ptr(auto_ptr<U>& rhs)
> >   : pointee(rhs.release())
> >   {}
> > template<class T>
> > inline auto_ptr<T>::~auto_ptr()
> > { delete pointee; }
> > template<class T>
> >   template<class U>
> >   inline auto_ptr<T>& auto_ptr<T>::operator=(auto_ptr<U>& rhs)
> >   {
> >     if (this != &rhs) reset(rhs.release());
> >     return *this;
> >   }
> > template<class T>
> > inline T& auto_ptr<T>::operator*() const
> > { return *pointee; }
> > template<class T>
> > inline T* auto_ptr<T>::operator->() const
> > { return pointee; }
> > template<class T>
> > inline T* auto_ptr<T>::get() const
> > { return pointee; }
> > template<class T>
> > inline T* auto_ptr<T>::release()
> > {
> >   T *oldPointee = pointee;
> >   pointee = 0;
> >   return oldPointee;}
>
> > template<class T>
> > inline void auto_ptr<T>::reset(T *p)
> > {
> >   if (pointee != p) {
> >     delete pointee;
> >     pointee = p;
> >   }
>
> > }
>
> > Anything wrong with the above ? (would be surprised if there is, as it
> > came from scott meyers)
>
> > > > Q1. Any problems with the above code ?
>
> There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
> on
> this), adding auto_ptr_ref for conversion, which supports rvalue
> initialization for auto_ptr. which is done transparently.
>
> void fun(auto_ptr<T> ptr);
> fun(auto_ptr(new T)); // rvalue -> auto_ptr_ref -> auto_ptr
>
>
>
> > > It works with g++.
>
> > Again, looks like an issue with visual studio 2008 express.
>
> there are two problem with visual C++ 2005 in this issue:
> 1. as extension, "explicit" does NOT work as standard says.
>    needs /Za switch to turn it off.
>
> 2. auto_ptr_ref use void* rather T*
>
> point 2 is fixed by VS 2008(none expression version,
> but I expression version should ship the same lib)
>
>
>
> > > > Q2. What is causing operator= not to be called and how to fix it ?
>
> > > A bug in your compiler?
>
> > > [snip]
>
> --
> Best Regards
> Barry

Thanks Barry.

Hendrik Schober

10/15/2008 3:22:00 PM

0

Barry wrote:
> [...]
> There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
> on
> this), adding auto_ptr_ref for conversion, which supports rvalue
> initialization for auto_ptr. which is done transparently.

The guy's name is Scott Meyers and the article is here:
http://www.aristeia.com/BookErrata/auto_ptr-u...

> [...]
> there are two problem with visual C++ 2005 in this issue:
> 1. as extension, "explicit" does NOT work as standard says.
> needs /Za switch to turn it off.

Do you have a repro for this? I'd be very interested.

> [...]
> Barry

Schobi

Barry

10/17/2008 12:53:00 AM

0

On Oct 15, 11:22 pm, Hendrik Schober <spamt...@gmx.de> wrote:
> Barry wrote:
> > [...]
> > There's a reversion for auto_ptr (IIRC, a article is proviede by Mayer
> > on
> > this), adding auto_ptr_ref for conversion, which supports rvalue
> > initialization for auto_ptr. which is done transparently.
>
>   The guy's name is Scott Meyers and the article is here:
>    http://www.aristeia.com/BookErrata/auto_ptr-u...
>
> > [...]
> > there are two problem with visual C++ 2005 in this issue:
> > 1. as extension, "explicit" does NOT work as standard says.
> >    needs /Za switch to turn it off.
>
>   Do you have a repro for this? I'd be very interested.
>

#include <memory>

int main()
{
std::auto_ptr<int> p1 = new int(10); // this shouldn't work
std::auto_ptr<int> p2(new int(10)); // should be like this!
}

=================
d:\>cl /EHsc test.cpp

Compile successfully!
=================

d:\>cl /EHsc /Za test.cpp
cl /EHsc /Za test.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42
for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

test.cpp
test.cpp(5) : error C2440: 'initializing' : cannot convert from 'int
*' to 'std::auto_ptr<_Ty>'
with
[
_Ty=int
]
Constructor for class 'std::auto_ptr<_Ty>' is declared
'explicit'
with
[
_Ty=int
]

===========================

--
Best Regards
Barry