【发布时间】:2014-02-04 22:37:28
【问题描述】:
我知道引用可以在 C++ 中使用extend the lifetime of a return value。有了这个哲学,我尝试了以下方法:我有三个类,“张量”、“视图”和“可变视图”。张量上的 Operator () 返回一个“const 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 根本不构建它:它要求“视图”中的构造函数是公共的。阅读 icc 的消息,这个想法似乎是编译器可能会复制右手的值,因此需要构造函数。
这是真的吗?是否有一种解决方法可以保留我想要构建的语法?顺便说一句,它们是构建的,为了避免基于 shared_ptr 或其他东西的低效实现,我需要保持“视图”对象不可复制。
编辑 1:
张量无法控制视图的生命周期。视图由访问者创建,它们的生命周期仅限于使用它们的语句,原因如下:
- 这些视图仅用于两件事:(i) 复制数据,(ii) 提取部分张量。
- 张量是实现写时复制语义的多维数组,这意味着视图不能是长期存在的对象:如果数据发生变化,它们就会过期。
编辑 2:
更改了伪代码描述(伙计们,如果您看到“...”,您认为它是可编译的吗?)使用基于 'icc' 而不是基于 clang/open64 的伪代码描述
【问题讨论】:
-
您能否发布一个 SSCCE(请参阅 sscce.org)。我很惊讶 gcc 编译了这个。
-
const view operator(int idx)?似乎不是运算符重载。operator是关键字。 -
你想说
operator ()(int idx)吗? -
当然这不是原始代码。我没有写 SSCCE,而是对它的外观有所了解。
-
不要按 const 值返回。它仅用于禁用某些复制省略优化
标签: c++ reference return-value