|
Boost Users : |
From: Edd Dawson (lists_at_[hidden])
Date: 2007-07-12 20:31:32
Hi again, Kirit!
Kirit Sælensminde wrote:
> That should force a string constructor only at the end of the chain, the
> rest of the time passing a pointer.
Based on your suggestion I've come up with a nice and simple solution. Rather
than doing a single copy at the end I can do once at the beginning, using this
crazy looking contraption:
template<typename T>
class ref_once_copied
{
public:
ref_once_copied(const T &obj) : obj_(new T(obj)), referenced_(false) { }
~ref_once_copied() { if (referenced_) delete obj_; }
operator T &() { referenced_ = true; return *obj_; }
private:
T *obj_;
bool referenced_;
};
It's a bit like boost::reference_wrapper<>, except that it makes a copy of the
object given to the constructor.
Copies are cheap because I'm only copying a pointer and a bool. I'm not *too*
bothered about copying these ~30 times :)
We know that the conversion-to-T&-operator will be called exactly once and after
it's been called we know this ref_once_copied object won't be used again or
copied anywhere else. So, we can flag the internal pointer for deletion in the
destructor.
I started out using a boost::shared_ptr<> for the obj_ member, but I realised
that approach outlined above would work just as well and also avoid the extra
overhead that the reference counting entails.
So, in async::call(), for each argument I find the value of:
boost::is_reference_wrapper<ArgType>::value || boost::is_scalar<ArgType>::value.
If this value is true, then I don't wrap the argument in a ref_once_copied<>,
otherwise I do.
Thus arguments that aren't explicitly wrapped by boost::ref() are copied once
and only once.
So I just wanted to say thanks! I wouldn't have gone down this road if it wasn't
for your suggestion. Perhaps you'll find a use for this in your implementation?
Kind regards,
Edd
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net