Prev: Does the C++ standard define the global function of " istream& operator >>(istream& in, string& str); "?
Next: return value optimization vs. returning a boost::shared_ptr of container
From: naikrosh on 12 Jun 2010 19:09 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 13 Jun 2010 05:42 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 13 Jun 2010 09:07 "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 13 Jun 2010 17:23 * 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 14 Jun 2010 17:59
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! ] |