views:

65

answers:

3

Hello

I'd like to use the following idiom, that I think is non-standard. I have functions which return vectors taking advantage of Return Value Optimization:

vector<T> some_func()
{
    ...
    return vector<T>( /* something */ );
}

Then, I would like to use

vector<T>& some_reference;
std::swap(some_reference, some_func());

but some_func doesn't return a LValue. The above code makes sense, and I found this idiom very useful. However, it is non-standard. VC8 only emits a warning at the highest warning level, but I suspect other compilers may reject it.

My question is: Is there some way to achieve the very same thing I want to do (ie. construct a vector, assign to another, and destroy the old one) which is compliant (and does not use the assignment operator, see below) ?

For classes I write, I usually implement assignment as

class T
{
    T(T const&);
    void swap(T&);
    T& operator=(T x) { this->swap(x); return *this; }
};

which takes advantage of copy elision, and solves my problem. For standard types however, I really would like to use swap since I don't want an useless copy of the temporary.

And since I must use VC8 and produce standard C++, I don't want to hear about C++0x and its rvalue references.

EDIT: Finally, I came up with

typedef <typename T>
void assign(T &x, T y)
{
    std::swap(x, y);
}

when I use lvalues, since the compiler is free to optimize the call to the copy constructor if y is temporary, and go with std::swap when I have lvalues. All the classes I use are "required" to implement a non-stupid version of std::swap.

+1  A: 

If you don't want useless copies of temporaries, don't return by value. Use (shared) pointers, pass function arguments by reference to be filled in, insert iterators, ....

Is there a specific reason why you want to return by value?

Pieter
Returning by value is convenient, natural, and my code is quite heavy: It would complicate it a lot to throw shared_pointers into the mix. The references to vectors I want to swap into are usually retrieved by iterators (I have lists of vectors of "generic vectors for which a std::swap is provided")
Alexandre C.
A: 

The only way I know - within the constraints of the standard - to achieve what you want are to apply the expression templates metaprogramming technique: http://en.wikipedia.org/wiki/Expression_templates Which might or not be easy in your case.

miquelramirez
Can you elaborate ? I don't see why I should use type trees here...
Alexandre C.
Just saw your answer to my comment, mentioning you're dealing with a collection of objects defined at run-time. Obviously enough, expression templates are only applicable if the collection of objects to combine is known at compile-time i.e. matrices A, B, C, D you want to add them up, arrays whose size has been defined at compile-time, etc.
miquelramirez
+1  A: 

Since std::vector is a class type and member functions can be called on rvalues:

some_func().swap(some_reference);
FredOverflow
That's standard. I accept your answer.
Alexandre C.