From: Fabian on
Hello,

I've got a class like this:

namespace Spimaging
{

class SPIMAGING_API StackOpZDivision: public IStackOperation
{
private:
const auto_ptr<Spimage> m_opDivisor;
public:
explicit StackOpZDivision(const Spimage* i_opDivisor);
....
};

StackOpZDivision::StackOpZDivision(const Spimage* i_opDivisor):
m_opDivisor(i_opDivisor) {}

}

When I try to compile it I get the message "error C2664:
'std::auto_ptr<_Ty>::auto_ptr(_Ty *) throw()' : cannot convert parameter 1
from 'const Spimaging::Spimage *' to 'Spimaging::Spimage *'"

I'm just trying to initialize a const auto_ptr with a const value. Is that
impossible?

Thx for your help,

Fabian
From: David Wilkinson on
Fabian wrote:
> Hello,
>
> I've got a class like this:
>
> namespace Spimaging
> {
>
> class SPIMAGING_API StackOpZDivision: public IStackOperation
> {
> private:
> const auto_ptr<Spimage> m_opDivisor;
> public:
> explicit StackOpZDivision(const Spimage* i_opDivisor);
> ...
> };
>
> StackOpZDivision::StackOpZDivision(const Spimage* i_opDivisor):
> m_opDivisor(i_opDivisor) {}
>
> }
>
> When I try to compile it I get the message "error C2664:
> 'std::auto_ptr<_Ty>::auto_ptr(_Ty *) throw()' : cannot convert parameter 1
> from 'const Spimaging::Spimage *' to 'Spimaging::Spimage *'"
>
> I'm just trying to initialize a const auto_ptr with a const value. Is that
> impossible?

Fabian:

The auto_ptr constructor does not take a const pointer argument. The const-ness
of the auto_ptr will prevent you from calling non-const methods of Spimage.

--
David Wilkinson
Visual C++ MVP
From: Igor Tandetnik on
"Fabian" <Fabian(a)discussions.microsoft.com> wrote in message
news:DB2B57CB-41E3-4B84-A6A7-1325058DAA6C(a)microsoft.com
> const auto_ptr<Spimage> m_opDivisor;
>
> StackOpZDivision::StackOpZDivision(const Spimage* i_opDivisor):
> m_opDivisor(i_opDivisor) {}
>
> I'm just trying to initialize a const auto_ptr with a const value. Is
> that impossible?

It doesn't matter whether the auto_ptr itself is const - you want the
type it refers to to be const. In other words, you want auto_ptr<const
Spimage>
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


From: David Wilkinson on
David Wilkinson wrote:
> Fabian wrote:
>> Hello,
>>
>> I've got a class like this:
>>
>> namespace Spimaging
>> {
>>
>> class SPIMAGING_API StackOpZDivision: public IStackOperation
>> {
>> private:
>> const auto_ptr<Spimage> m_opDivisor;
>> public:
>> explicit StackOpZDivision(const Spimage* i_opDivisor);
>> ...
>> };
>>
>> StackOpZDivision::StackOpZDivision(const Spimage* i_opDivisor):
>> m_opDivisor(i_opDivisor) {}
>>
>> }
>>
>> When I try to compile it I get the message "error C2664:
>> 'std::auto_ptr<_Ty>::auto_ptr(_Ty *) throw()' : cannot convert
>> parameter 1 from 'const Spimaging::Spimage *' to 'Spimaging::Spimage *'"
>>
>> I'm just trying to initialize a const auto_ptr with a const value. Is
>> that impossible?
>
> Fabian:
>
> The auto_ptr constructor does not take a const pointer argument. The
> const-ness of the auto_ptr will prevent you from calling non-const
> methods of Spimage.

Fabian:

Oops, I forgot to tell you that when I tested this, I used auto_ptr<const Spimage>.

Why do you think you want the auto_ptr itself to be constant?

--
David Wilkinson
Visual C++ MVP
From: Alf P. Steinbach on
* Fabian:
>
> namespace Spimaging
> {
>
> class SPIMAGING_API StackOpZDivision: public IStackOperation
> {
> private:
> const auto_ptr<Spimage> m_opDivisor;
> public:
> explicit StackOpZDivision(const Spimage* i_opDivisor);
> ...
> };
>
> StackOpZDivision::StackOpZDivision(const Spimage* i_opDivisor):
> m_opDivisor(i_opDivisor) {}
>
> }
>
> When I try to compile it I get the message "error C2664:
> 'std::auto_ptr<_Ty>::auto_ptr(_Ty *) throw()' : cannot convert parameter 1
> from 'const Spimaging::Spimage *' to 'Spimaging::Spimage *'"
>
> I'm just trying to initialize a const auto_ptr with a const value. Is that
> impossible?

As others have already remarked, you can have std::auto_ptr<Spimage const> if
you want.

A completely different point (not what you're asking about): when using a
std::auto_ptr as non-static member you can't (meaningfully) have an ordinary T(T
const&) copy constructor, because std::auto_ptr doesn't have one. std::auto_ptr
transfers ownership for the contained raw pointer, and so isn't copy
constructible. This isn't necessarily bad, but it's worth being aware of.

Similarly, having something 'const', or a reference, as non-static data member
prevents assignment.

So instances of StackOpZDivision can not be used as standard container elements,
which must be copy constructible and assignable.

However, raw pointers to such instances can.

A third point: if you really want to transfer ownership (deallocation
responsibility) from the code that creates a StackOpZDivision instance, then the
constructor argument should be a std::auto_ptr or other smart pointer that
transfers ownership. If on the other hand what you want is not ownership
transfer but automated destruction of shared pointers, then use a shared
ownership smart pointer such as e.g. boost::shared_ptr. Using shared_ptr has
the additional advantage over auto_ptr that you can use shared_ptr instances as
standard container elements, because shared_ptr is copy constructible.


Cheers, & hth.,

- Alf


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?