C++返回无法复制的临时值和对象

Jua*_*njo 5 c++ reference return-value

我知道引用可以延长 C++中返回值的生命周期.有了这个哲学,我尝试了以下内容:我有三个分支,'张量','视图'和'mutable_view'.张量上的Operator()返回"const视图"对象.此视图具有私有拷贝构造函数,因此无法复制视图,因为它保留有关可能无法在当前语句之外生存的张量的信息.

#include <iostream>
#include <algorithm>

struct tensor {

  int data[10];

  class view {
    const int *const data;

    view();
    view(const view &);
  public:
    view(const int *new_data) : data(new_data) {}
    int operator*() const { return *data; }
  };

  class mutable_view {
    int *const data;

    mutable_view();
    mutable_view(const mutable_view &);
  public:
    mutable_view(int *new_data) : data(new_data) {}

    void operator=(const view &v) {
      *data = *v;
    }
  };

  tensor(int n) {
    std::fill(data, data+10, n);
  }

  const view operator()(int ndx) const {
    return view(data + ndx);
  }

  mutable_view at(int ndx) {
    return mutable_view(data + ndx);
  }
};


int main()
{

  tensor a(1);
  tensor b(2);

  b.at(2) = a(2);

  for (int i = 0; i < 10; i++)
    std::cout << "a[i] = " << b.data[i] << std::endl;

  for (int i = 0; i < 10; i++)
    std::cout << "b[i] = " << b.data[i] << std::endl;

  exit(0);
}
Run Code Online (Sandbox Code Playgroud)

问题在于,虽然此代码在gcc中工作(取决于版本),但icc表示警告,open64根本不构建它:它要求来自"view"的构造函数是公共的.读取icc的消息时,想法似乎是编译器可能会复制右手值,因此需要构造函数.

这是真的吗?是否有一种解决方法可以保留我想要构建的语法?顺便说一下,为了避免基于shared_ptr或其他东西的低效实现,我需要保持"视图"对象不可复制.

编辑1:

张量无法控制视图的生命周期.视图由访问者创建,其生命周期仅限于使用它们的语句,原因如下:

  • 这些视图仅用于两件事:(i)复制数据,(ii)提取张量的部分.
  • 张量是实现写时复制语义的多维数组,这意味着视图不能是长期存在的对象:如果数据发生变化,它们就会过期.

编辑2:

更改了伪代码描述(伙伴们,如果你看到'...'你希望它可以编译吗?),一个建立在'icc'而不是在clang/open64上

asc*_*ler 2

继续让默认的复制构造函数公开。并记录 aviewmutable_view在其被更改或销毁时“无效” tensor

这与标准库处理具有依赖于另一个对象的生命周期的迭代器、指针和引用的方式类似。