I don't think you can do this with current C++. You need the move semantics that will be introduced in C++x0.
The original Guru of the Week article is here: Guru of the Week #15.
Part of your answer might come from Herb himself, in "A candidate for the most important const" - the "const" part of assigning a temporary to a reference is indeed important.
So it would appear as if this is a bug in the original article.
I always considered that passing address parameters (whether by reference or pointer) required an understanding about the lifetime of the thing passed. Period. End of Discussion. This seems just an attribute of an un-garbage-collected/NOT-reference-managed environment.
This is one of the benefits of GC.
In c++ sometimes the lifetime issues were solved by:
X::clone
or by explicit documentation of the interface eg:
"it is up to the instantiator of Y to ensure that the instance of X passed in parameter x remains in existence for the entire lifetime of Y"
or by
explicit copying of x in the guts of the receiver.
That's just c++. That c++ added a guarantee on const references was nice (and really somewhat necessary) but that was that.
Thus I consider the code as shown in the question to be wrong and am of the opinion it should have been:
int main()
{
MyWorker w;
GenericTableAlgorithm a( "Customer", w);
a.Process();
}
I think this is a tricky part that is not too clear. There was a similar question just a couple of days ago.
By default temporaries are destroyed in reverse order of construction when the full-expression in which they were created completes. Up to here everything is fine and understood, but then exceptions arise (12.2 [class.temporary]/4,5) and things become confusing.
Instead of dealing with the exact wording and definitions in the standard I will approach the problem from an engineering / compiler perspective. Temporaries are created in the stack, when a function completes the stack frame is freed (the stack pointer is moved back to the original position before the function call started).
This implies that a temporary can never survive the function in which it was created. More exactly, it cannot survive the scope where it was defined, even if it can in fact survive the full-expression in which it was created.
None of the exceptions in the standard falls out of this restriction, in all cases the lifetime of the temporary is extended to a point that is guaranteed not to exceed the function call in which the temporary was created.