Re: Copying shared_ptr<T const>
Jeremy Jurksztowicz wrote:
Please excuse me if this topic is treated elswhere. I would appreciate
a pointer.
Consider:
void doSomething (shared_ptr<T const> const&);
When passing a shared_ptr<T> (non-const) to this function, will a new
shared_ptr object be constructed for the paramater to reference, or
will the original non-const shared_ptr be coerced?
In the latter case, there seems no need for a reference type qualifier
at all, ie:
void doSomething(shared_ptr<T const>);
Would be prefferable. This raises a question of performance. Surely
incrementing and decrementing a use count is much more demanding than
passing a C++ reference.
Is my understanding of the situation correct, am I missing something,
or am I totally off the mark?
You are right, a temporary shared_ptr<T const> is created if the source
is shared_ptr<T>. shared_ptr<T const> const & cannot be bound directly
to a shared_ptr<T>. It would've been nice if we could inform the
compiler that it is safe to perform this binding as a shared_ptr<T> is
struct { T * pt; C * pc; }; // C == control block, independent of T
and a shared_ptr<T const> is
struct { T const * pt; C * pc; };
so the two are layout-compatible (by design.)
But we can't, and there is no way to somehow enable this optimization
from the library side (short of using inheritance hacks that would open
const-correctness holes.)
What we can do today is to supply two overloads for doSomething (but
this would make passing a shared_ptr<Derived> ambiguous) or make it a
template. reinterpret_cast at the caller side is possible, but doesn't
seem worth it. :-)
As for
In the latter case, there seems no need for a reference type qualifier
at all, ie:
void doSomething(shared_ptr<T const>);
this is only true if all callers pass shared_ptr<T>. If doSomething is
also invoked with a genuine shared_ptr<T const>, the original version
would save one copy.
Finally, if doSomething is
static shared_ptr<T const> s_pt;
void doSomething( shared_ptr<T const> const & pt )
{
s_pt = pt;
}
and move semantics are accepted for C++0x, we would be able to add
void doSomething( shared_ptr<T const> && pt )
{
s_pt = std::move( pt );
}
and bring the reference count updates down to the minimum required for
s_pt = <the argument of doSomething>;
(but I don't have a &&-capable compiler to test that, so I could be
wrong.)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]