From: naikrosh on
Is there a safe way to treat Foo<T>* as a Foo<const T>* ?

Assume that we have freedom to modify template Foo and it has not been
specialized... but can be specialized if necessary. For sake of
simplicity lets assume the following simplistic definition of Foo:

template<class T>
struct Foo {
T* ptr;
bool flag;
~Foo(){}; // This makes Foo ... not a POD type
};

I know reinterpret_cast would do it. But I am not sure if its the
safe.

-Roshan

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

From: Bo Persson on
naikrosh(a)gmail.com wrote:
> Is there a safe way to treat Foo<T>* as a Foo<const T>* ?
>
> Assume that we have freedom to modify template Foo and it has not
> been specialized... but can be specialized if necessary. For sake of
> simplicity lets assume the following simplistic definition of Foo:
>
> template<class T>
> struct Foo {
> T* ptr;
> bool flag;
> ~Foo(){}; // This makes Foo ... not a POD type
> };
>
> I know reinterpret_cast would do it. But I am not sure if its the
> safe.
>
> -Roshan

No, they are different types, just like any other different types.
Foo<Bar> and Foo<const Bar> are different types, just like Foo<Bar>
and Foo<int>.

Using a reinterpret_cast will not really work either, it just tells
the compiler to "shut up and do it!".

That way it will not tell you that it doesn't work. :-)


Bo Persson



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

From: Paul Bibbings on
"naikrosh(a)gmail.com" <naikrosh(a)gmail.com> writes:

> Is there a safe way to treat Foo<T>* as a Foo<const T>* ?
>
> Assume that we have freedom to modify template Foo and it has not been
> specialized... but can be specialized if necessary. For sake of
> simplicity lets assume the following simplistic definition of Foo:
>
> template<class T>
> struct Foo {
> T* ptr;
> bool flag;
> ~Foo(){}; // This makes Foo ... not a POD type
> };
>
> I know reinterpret_cast would do it. But I am not sure if its the
> safe.
>

I think that a more appropriate question would be "how can I
re-design/refactor my code so that I don't have to ask the question
"is there a safe way to treat Foo<T>* as a Foo<const T>*." If you
are finding that your question has relevance to your design, then I
would suggest that your design has problems elsewhere.

Perhaps you could provide a small code snippet illustrating the kind of
scenario in which this question has arisen for you.

Regards

Paul Bibbings

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

From: Alf P. Steinbach on
* naikrosh(a)gmail.com, on 13.06.2010 12:09:
> Is there a safe way to treat Foo<T>* as a Foo<const T>* ?

Not in general, but see below.


> Assume that we have freedom to modify template Foo and it has not been
> specialized... but can be specialized if necessary. For sake of
> simplicity lets assume the following simplistic definition of Foo:
>
> template<class T>
> struct Foo {
> T* ptr;
> bool flag;
> ~Foo(){}; // This makes Foo ... not a POD type
> };
>
> I know reinterpret_cast would do it. But I am not sure if its the
> safe.

Regarding just the pointer value it is for all practical purposes safe when you
know that Foo is not specialized on the constness.

However, formally that reinterpret_cast is, as I recall, unspecified behavior.

And it allows you to do Bad Things because Foo<T> can have, and in particular in
your example does have, semantics analogous to T*. And then the conversion
Foo<T>* -> Foo<T const>* is analogous to T** -> T const**, which is strictly
forbidden. See the FAQ item titled "Why am I getting an error converting a Foo**
-> Foo const**?" currently available at e.g. <url:
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17>.


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>

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

From: Ulrich Eckhardt on
naikrosh(a)gmail.com wrote:
> Is there a safe way to treat Foo<T>* as a Foo<const T>* ?
>
> Assume that we have freedom to modify template Foo

I could imagine Foo<T> publicly deriving from Foo<T const>. For e.g.
boost::shared_ptr<>, you can also convert a shared_ptr<T> into a
shared_ptr<T const>, you may want to do something similar.

> For sake of simplicity lets assume the following simplistic
> definition of Foo:
>
> template<class T>
> struct Foo {
> T* ptr;
> bool flag;
> ~Foo(){}; // This makes Foo ... not a POD type
> };
>
> I know reinterpret_cast would do it. But I am not sure if its the
> safe.

Imagine you could somehow get this to work, it would break const
correctness:

int const answer = 42;
Foo<int> f;
// the following line wouldn't compile for good reason
// f.ptr = &answer;
Foo<int const>* p = &f; // assume some conversion that makes it work
p->ptr = &answer;

Now "f.ptr" points to an int constant, allowing it to be modified. You don't
want that. Maybe that isn't an issue in your actual code, but then your
simplistic example is a bit too much so. ;)

Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932


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