Re: Treating Foo<T>* as Foo<const T>*
On 15 June, 15:12, Edward Rosten <edward.ros...@gmail.com> wrote:
On Jun 15, 10:03 am, Nick Hounsome <nick.houns...@gmail.com> wrote:
On 13 June, 11:09, "naikr...@gmail.com" <naikr...@gmail.com> wrote:
This has been debated here before. Perhaps I have a more coherent
argument this time.
Is there a safe way to treat Foo<T>* as a Foo<const T>* ?
Are you absolutely sure that you dont want const Foo<T>*?
Yes...
IMHO It is rarely useful to have Foo<const T> because Foo can always
protect instance of T whether they are const or not - All you acheive
is making the implementation harder. (Foo<const T*> MIGHT make sense).
Unfortunately, you are mistaken. Consider:
template<class C> class Foo
{
private:
C* ptr;
public:
Foo(C* p)
:ptr(p);
C* get(){ return ptr; }
const C* get() const { return ptr; }
};
Now consider you have a function like this:
void func(const Foo<int>& f)
{
Foo<int> not_const_anymore(f);
*not_const_anymore.get() = 0;
}
Because you can copy construct a non-const object from a const one,
you can with some effort circumvent the access controls.
This is only because your Foo is seriuosly flawed.
It can be prevented with:
Foo(const Foo<T>&) = delete; // or private unimplemented
Foo& operator=(const Foo<T>&) = delete; // or provate unimplemented
As a good general rule any class containing pointers should declare
copy ctor and assignment operator.
Compare your class Foo with std::vector - nobody uses vector<const
int> but vector protects its content with overloads like
reference operator[] ( size_type n );
const_reference operator[] ( size_type n ) const;
I agree 100%. When a class has value semantics (e.g. vector<int>) a
const class behaves as if the values it points to are const. That is
nice since a const vector works as a const array. However, if you have
an object with reference semantics, it is impossible so make a const
object behave as if it points to const data properly.
The problem is that const behaves very subtly differently for pointers
than for classes. This is well illustrated by the fact that it is
impossible to get pointer like semantics with classes. Many people
(myself included) understand the precise reasons behind how this
difference manifests, but nevertheless disagree.
The reason is that const A* is just a const version of A*, so the
conversion can happen freely. In this case, the object IS NOT
constant.
However, const A is a version of A, but the object IS constant.
It is straightforward to provide a conversion from Foo<T> to Foo<const
T>
if that is what you need.
As a bonus it does away with the need for all the pointers and/or
references.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]