我正在尝试按如下方式实现列表类
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;
}
我喜欢这种模式,因为它使A.subList(1).subList(2)
之类的东西成为可能,这使得以递归方式实现某些东西变得很方便。我的实际案例更复杂,但我已将其剥离为代表核心理念的东西。
这会在以下
中产生问题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'
我的猜测是,在第二行中,A.subList(5)
在this
的通话期间为operator*=
,因此保证在整个通话中持续,但在第二行case只是一个参数,因此它的生命周期没有扩展。我可以通过用
NOlist Atmp(A.subList(5)); // make the subList non-temporary
triple(Atmp); // modify the subList
...但我想知道是否有更优雅的解决方案。基本上我想在函数调用期间延长临时生命,并允许它在生命周期中用作左值。
答案 0 :(得分:0)
我认为你的函数triple需要参考。如果你使用参数by-value,它将起作用(相当于你编写的代码作为一种变通方法),但它不会要求你手动创建临时对象(相反,它将在函数中创建) - 来电时间。)
假设您的NOlist
创建/复制起来很便宜,那么这是一个有效的解决方案。或者,您可以只为该用例使用特殊代理类型。