将临时函数作为左值传递给函数

时间:2017-04-30 19:44:45

标签: c++

我正在尝试按如下方式实现列表类

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

...但我想知道是否有更优雅的解决方案。基本上我想在函数调用期间延长临时生命,并允许它在生命周期中用作左值。

1 个答案:

答案 0 :(得分:0)

我认为你的函数triple需要参考。如果你使用参数by-value,它将起作用(相当于你编写的代码作为一种变通方法),但它不会要求你手动创建临时对象(相反,它将在函数中创建) - 来电时间。)

假设您的NOlist创建/复制起来很便宜,那么这是一个有效的解决方案。或者,您可以只为该用例使用特殊代理类型。