Reputation: 1095
I am trying to implement a list class as follows
class NOlist { // "Non-Owning" list
protected:
int nData;
double* data;
// Construct given an existing data array
NOlist(int nDataArg, double* dataArg) : nData(nDataArg), data(dataArg) {}
public:
// Copy constructor
NOlist(const NOlist&)=default;
// Return NOlist representing sub-list
NOlist subList(const int at) {
return NOlist(nData-at, data+at);
}
// Operators
NOlist& operator*=(const double& factor) {
for(int i = 0; i < nData; i++) {
data[i] *= factor;
}
return *this;
}
};
struct List : public NOlist { // Wrapper (responsible for memory management only)
List(const int nDataArg) : NOlist(nDataArg, new double[nDataArg]) {}
~List() { delete[] data; }
};
void triple(NOlist& arg) {
arg *= 3.0;
}
I like this pattern because it makes it possible to things like A.subList(1).subList(2)
, which makes it convenient to implement some things recursively. My actual case is more complicated, but I've stripped it down to something which represents the core idea.
This creates a problem in the following
List A(50);
// [code to set A...]
A.subList(5) *= 3; // works
triple(A.subList(5)); // error: invalid initialization of non-const reference of type 'NOlist&' from an rvalue of type 'NOlist'
My guess is that, in the second-last line, A.subList(5)
is this
during the call to operator*=
and is therefore guaranteed to last for the entire call, but in the second case it is just an argument and therefore its lifetime gets no extension. I can get around the error by replacing the last line with
NOlist Atmp(A.subList(5)); // make the subList non-temporary
triple(Atmp); // modify the subList
...but I'm wondering whether there is a more elegant solution. Essentially I would like to prolong the life of a temporary for the duration of a function call and allow it to be used as an lvalue during that lifespan.
Upvotes: 0
Views: 97
Reputation: 19374
I presume your function triple takes a reference. If you make it take the parameter by-value, it will just work (equivalent to the code you wrote as a workaround) but it won't require you to manually create the temporary object (instead, it will be created at function-call time.)
Assuming your NOlist
is cheap to create/copy, that's a valid solution. Alternatively, you could have a special proxy type just for that use case.
Upvotes: 0