Reputation: 3357
I have class foo
that manages a vector
of float
s of fixed length and some metadata. I have implemented a naive overload for operator*:
constexpr int numOfElements = 9;
class foo {
public:
foo()
: x(0), y(0), data(numOfElements)
{}
foo operator*(float value) {
foo result;
for (size_t k = 0; k < this->data.size(); ++k)
result.data[k] = this->data[k] * value;
return result;
}
int x;
int y;
std::vector<float> data;
};
later, I use it in the following way:
some_foo = *ptr_to_another_foo * 5;
where some_foo
and ptr_to_another_foo
were defined elsewhere and hold some values. This computes the correct result. However, result foo
in the overloaded operator creates another object which causes memory allocation which is unacceptable due to performance reasons. Since some_foo
already has memory allocated for data
, is there a way to implement the overloaded operator in such a way that some_foo.data
s memory will be used instead of allocating the temporary foo result
?
I could always implement a C-like pointer-based multiplication function, but I would like to do something more idiomatic in C++.
Upvotes: 1
Views: 115
Reputation: 238351
Do not return a foo
. Instead, return a wrapper object which refers to *this
and can be used as operand for assignment into another foo
, changing its state with the multiplied values. This has the caveat that the returned wrapper becomes invalid in case the referred foo
is destroyed.
A general pattern for this idea is called expression templates. This is commonly used in linear algebra libraries.
Upvotes: 2
Reputation: 122457
Write a operator*=
that multiplies the elements in place:
foo& operator*=(float value) {
for (size_t k = 0; k < this->data.size(); ++k)
this->data[k] *= value;
return *this;
}
If later you realize that you do need also operator*
you can implement it in terms of operator*=
:
foo operator*(float value) const {
foo result = *this;
result *= value;
return result;
}
Note that operator*
is expected to return a new object and not modify this
(it should be a const
method), while operator*=
is expected to return a reference to *this
(after modifying it). If you want to make the operation in place, better use the compound *=
.
Upvotes: 3