c++11 - How to avoid unnecessary instances using rvalue references in C++ -
i create custom container container
stores data in individual arrays. however, facilitate easy iterations on container, provide 'view' on container overloading operator[]
, return single struct value
holds container variables references actual container. got 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 , output temporary container c; cout << c[2].data() << endl; // output: 3 - ok! // create, modify , output copy value v = c[2]; cout << v.data() << endl; // output: 3 - ok! v.data() = 8; cout << v.data() << endl; // output: 8 - ok! // create , output reference value&& vv = c[2]; cout << vv.data() << endl; // output: 8 - ok, weird: // shouldn't dangling reference? cout << vv.data() << endl; // output: 468319288 - bad, that's expected... }
the code above working far can tell, i'm wondering if use best approach here:
- is correct return
value
rvalue reference if want avoid unnecessary copying? - is use of
std::forward
correct? should usestd::move
(both work in example) or else? - the output of compiled program stated in comments. there way can avoid dangling reference when declare
value&& vv...
(or forbid syntactically)?
edit 1
i made small change source code value
instance not directly created in operator[]
method in helper function. change anything? should use makevalue(int i)
method shown or need use std::move
/std::forward
in here?
is correct return value rvalue reference if want avoid unnecessary copying?
no. returning rvalue references isn't helper std::move
or std::forward
flat-out wrong. rvalue references still references. returning reference temporary or local variable has been wrong , still wrong. these same c++ rules of old.
is use of
std::forward
correct? should usestd::move
(both work in example) or else?
the answer previous question kinda makes 1 moot.
the output of compiled program stated in comments. there way can avoid dangling reference when declare
value&& vv...
(or forbid syntactically)?
it's not value&& vv = c[2];
part creates dangling reference. it's operator[]
itself: see answer first question.
rvalue references change pretty nothing in case. things have done:
value operator[](int i) { return value(data_[i]); }
any compiler worth using optimise direct initialisation of return value without copies or moves or anything. dumb/worthless/weird/experimental compilers @ worst involve move (but why use such thing serious stuff?).
so, line value v = c[2];
initialise v
directly. line value&& vv = c[2];
initialise temporary , bind rvalue reference variable. these have same property const&
used to, , extend lifetime of temporary lifetime of reference, wouldn't dangling.
in sum, same old c++ of still works, , still gives results both correct , performant. not forget it.
Comments
Post a Comment