I've got a C++ data-structure that is a required "scratchpad" for other computations. It's not long-lived, and it's not frequently used so not performance critical. However, it includes a random number generator amongst other updatable tracking fields, and while the actual value of the generator isn't important, it is important that the value is updated rather than copied and reused. This means that in general, objects of this class are passed by reference.
If an instance is only needed once, the most natural approach is to construct them whereever needed (perhaps using a factory method or a constructor), and then passing the scratchpad to the consuming method. Consumers' method signatures use pass by reference since they don't know this is the only use, but factory methods and constructors return by value - and you can't pass unnamed temporaries by reference.
Is there a way to avoid clogging the code with nasty temporary variables? I'd like to avoid things like the following:
scratchpad_t<typeX<typeY,potentially::messy>, typename T> useless_temp = factory(rng_parm);
xyz.initialize_computation(useless_temp);
I could make the scratchpad intrinsically mutable and just label all parameters const &, but that doesn't strike me as best-practice since it's misleading, and I can't do this for classes I don't fully control.  Passing by rvalue reference would require adding overloads to all consumers of scratchpad, which kind of defeats the purpose - having clear and concise code.
Given the fact that performance is not critical (but code size and readability are), what's the best-practice approach to passing in such a scratchpad? Using C++0x features is OK if required but preferably C++03-only features should suffice.
Edit: To be clear, using a temporary is doable, it's just unfortunate clutter in code I'd like to avoid. If you never give the temporary a name, it's clearly only used once, and the fewer lines of code to read, the better. Also, in constructors' initializers, it's impossible to declare temporaries.
 
                        
While it is not okay to pass rvalues to functions accepting non-const references, it is okay to call member functions on rvalues, but the member function does not know how it was called. If you return a reference to the current object, you can convert rvalues to lvalues:
Note how the call to
self()yields an lvalue expression even thoughscratchpad_tis an rvalue.Well, you could use templates...
If you call
foowith an rvalue parameter,Scratchwill be deduced toscratchpad_t, and thusScratch&&will bescratchpad_t&&.And if you call
foowith an lvalue parameter,Scratchwill be deduced toscratchpad_t&, and because of reference collapsing rules,Scratch&&will also bescratchpad_t&.Note that the formal parameter
scratchpadis a name and thus an lvalue, no matter if its type is an lvalue reference or an rvalue reference. If you want to passscratchpadon to other functions, you don't need the template trick for those functions anymore, just use an lvalue reference parameter.By the way, you do realize that the temporary scratchpad involved in
xyz.initialize_computation(scratchpad_t(1, 2, 3));will be destroyed as soon asinitialize_computationis done, right? Storing the reference inside thexyzobject for later user would be an extremely bad idea.Yes, that is also possible, although I would rename it to make the intention clearer: