Boost logo

Boost :

From: Ed Brey (brey_at_[hidden])
Date: 2002-07-19 13:26:50


"Peter Dimov" <pdimov_at_[hidden]> wrote in message news:005b01c22f3e$70eccc40$1d00a8c0_at_pdimov2...
>
> No, whether the template parameter is const or not doesn't matter. In
>
> shared_ptr<T const> pt(new T);
>
> the type that pt has been initialized with is 'T', not 'T const', just like in
>
> shared_ptr<T const> pt2(new Y);
>
> 'pt2' is initialized with 'Y'.
>
> The only place where the 'counted_base const *' problem appears in practice
> (AFAIK) is:
>
> class X: public counted_base // allow this -> shared_ptr conversions
> {
> public:
>
> shared_ptr<X> shared_this()
> {
> return shared_ptr<X>(this); // OK
> }
>
> shared_ptr<X const> shared_this() const
> {
> return shared_ptr<X const>(this); // should be a compile-time error
> // return shared_ptr<X const>(const_cast<X*>(this)); // not pretty but OK
> }
> };
>
> If your experience differs from match my explanation, then I've probably
> done something wrong. :-)

You explanation is absolutely correct. My expectation, based on code inspection alone, that <T const> wouldn't work properly with shared_ptr was incorrect. I'm glad that you highlighted that the object itself is typically non-const; I didn't pick up on that detail. I was also led astray by the difference in capability in this regard between intrusive_ptr and shared_ptr. Logically, it seemed to me that if <T const> didn't work with intrusive_ptr, it shouldn't have worked with shared_ptr.

I see now where the difference lies. Shared_ptr has the luxury of two pointers, one const to the object, and one non-const to its count. Intrusive_ptr has just one count, so it must be const. This also points to an opportunity. It seems to me that the same reasoning that allowed you to write "not pretty but OK" above should also allow intrusive_ptr to cast away constness when accessing the count.

On a larger scale, this discussion of casting away constness brings back the issue of logical constness and whether mutable should be used instead. This would allow x_ptr's constructor to take const objects. This is good, since there are cases, such as in your example, where the object is already const by the time it gets to x_ptr's constructor.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk