I know that references can extend the lifetime of a return value in C++. With this phylosophy, I tried the following: I have three clases, 'tensor', 'view' and 'mutable_view'. Operator () on a tensor returns a "const view" object. This view has a private copy constructor so that the view cannot be copied, as it keeps information about the tensor that might not survive beyond the current statement.
#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);
}
The problem is that, while this code works in gcc (depends on the version), icc signals a warning and open64 simply does not build it: it demands that the constructors from 'view' be public. Reading icc's message the idea seems to be that the right hand value could be potentially copied by the compiler and thus constructors are needed.
Is this really true? Is there a workaround that preserves the syntax I want to build? By the way they are built, and in order to avoid inefficient implementations based on shared_ptr or other stuff, I need to keep the 'view' objects un-copiable.
Edit 1:
tensor cannot control the lifetime of the views. The views are created by the accessors and their lifetime is limited to the statement where they are used, for the following reasons:
Edit 2:
Changed the pseudocode description (guys, if you see '...' do you expect it to be compilable?) with one that builds on 'icc' and does not on clang/open64
Go ahead and let the default copy constructors be public. And document that a view
or mutable_view
is "invalidated" when its tensor
is changed or destroyed.
This parallels how the Standard Library deals with iterators, pointers, and references that have a lifetime which depends on another object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With