I would like to create a custom container Container
that stores data in individual arrays. However, to facilitate easy iterations over the container, I provide a 'view' on the container by overloading operator[]
and return a single struct Value
that holds all container variables as references to the actual container. This is what I got so far:
#include <iostream>
using namespace std;
struct Value {
Value(int& data) : data_(data) { }
int& data() { return data_; }
int& data_;
};
struct Container {
Value makeValue(int i) { return Value(data_[i]); } // EDIT 1
Value&& operator[](int i) {
// return std::forward<Value>(Value(data_[i]));
return std::forward<Value>(makeValue(i)); // EDIT 1
}
int data_[5] = {1, 2, 3, 4, 5};
};
int main(int, char**)
{
// Create and output temporary
Container c;
cout << c[2].data() << endl; // Output: 3 - OK!
// Create, modify and output copy
Value v = c[2];
cout << v.data() << endl; // Output: 3 - OK!
v.data() = 8;
cout << v.data() << endl; // Output: 8 - OK!
// Create and output reference
Value&& vv = c[2];
cout << vv.data() << endl; // Output: 8 - OK, but weird:
// shouldn't this be a dangling reference?
cout << vv.data() << endl; // Output: 468319288 - Bad, but that's expected...
}
The code above is working as far as I can tell, but I'm wondering if I use the best approach here:
- Is it correct to return the
Value
as an rvalue reference if I want to avoid unnecessary copying? - Is the use of
std::forward
correct? Should I usestd::move
(both will work in this example) or something else? - The output of the compiled program is stated in the comments. Is there any way I can avoid the dangling reference when I declare
Value&& vv...
(or even forbid it syntactically)?
EDIT 1
I made a small change to the source code so that the Value
instance is not directly created in the operator[]
method but in another helper function. Would that change anything? Should I use the makeValue(int i)
method as shown or do I need to use std::move
/std::forward
in here?