我知道引用可以extend the lifetime of a return value在 C++ 中。有了这个哲学,我尝试了以下方法:我有三个类,“tensor”、“view”和“mutable_view”。张量上的运算符 () 返回一个“常量 View ”对象。此 View 有一个私有(private)复制构造函数,因此无法复制该 View ,因为它保留了有关张量的信息,这些信息可能不会在当前语句之后继续存在。
#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);
}
问题是,虽然此代码在 gcc 中有效(取决于版本),但 icc 发出警告并且 open64 根本不构建它:它要求“ View ”中的构造函数是公开的。阅读 icc 的消息,这个想法似乎是右手值可能会被编译器复制,因此需要构造函数。
这是真的吗?是否有一种解决方法可以保留我想要构建的语法?顺便说一下,为了避免基于 shared_ptr 或其他东西的低效实现,我需要保持“ View ”对象不可复制。
编辑 1:
张量无法控制 View 的生命周期。 View 由访问者创建,它们的生命周期仅限于使用它们的语句,原因如下:
- 这些 View 仅用于两件事:(i) 复制数据,(ii) 提取部分张量。
- 张量是实现写时复制语义的多维数组,这意味着 View 不能是长期存在的对象:如果数据发生变化,它们就会过期。
编辑 2:
更改了伪代码描述(伙计们,如果你看到“...”,你认为它是可编译的吗?)用一个建立在“icc”上而不是在 clang/open64 上的伪代码描述
最佳答案
继续,让默认的复制构造函数公开。并记录 view
或 mutable_view
在 tensor
更改或销毁时“失效”。
这类似于标准库处理迭代器、指针和引用的方式,这些迭代器、指针和引用的生命周期取决于另一个对象。
关于C++ 返回不可复制的临时值和对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21565030/