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