views:

263

answers:

2

I have a class which contains a few boost::numeric::ublas::matrix's within it. I would like to overload the class's operators (+-*/=) so that I can act on the set of matrices with one statement.

However this seems to require temporary instances of my class to carry values around without modifying the original class. This makes sense to me, however, when I create a new instance within the function and return it I get:

warning: reference to local variable ‘temp’ returned

I'm pretty new to c++ and the examples of operator overloading seem to all return new temporary objects. I would also like to avoid the overhead in instantiating new matrix's, which leads me towards looping over all elements. How should I go about this? Performance is a concern.

+1  A: 

The conventional way of operator overloading is as follows. (I think)

Your in-place operators are defined as members, such as:

foo& operator+=(const foo& rhs);
foo& operator*=(const foo& rhs);
// etc.

Which simply do what they need on *this:

foo& operator+=(const foo& rhs)
{
    // add elements together

    return *this;
}

Then make free functions, and let the copying be done in the arguments:

const foo operator+(foo lhs, const foo& rhs)
{
    return lhs += rhs;
}

The return value is const because it's strange to do:

foo a, b, c;
(a + b) = c;

In the same way it's strange to do:

int a, b, c;
(a + b) = c;

Though you'll get differing opinions on that. This is how you reuse your code, and have the copy done for you automatically. Very terse and readable.

Like Neil and I said above, though, if you're creating new data, at some point that data needs to have a new place to stay. Use mutating operators when you can to avoid this, but some things simply cannot be escaped.

It might not even be a problem. If it is, try to optimize the memory allocations you have; these are likely the slowest part. I'm not sure, but I think most boost classes let you specify an allocator. The boost memory pool library may be useful here.

GMan
Interesting, and thank you. So far I have been just using in-place operators and carefully manipulating a single temporary object.
ccook
+2  A: 

If you're using boost already, I'd strongly suggest using boost::operators along with your example.

You'll get several benefits:

  1. You'll only need to overload the +=/-=/= operators, and get the +/-/ operators for free.
  2. You'll have a optimal implementation of the freely implemented operators.
  3. You'll get rid of the problem you posted, because you'll be implementing the = versions, which require less design.
Kornel Kisielewicz
Thank you, I will give this a shot on Monday!
ccook