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
valuervalue reference if want avoid unnecessary copying? - is use of
std::forwardcorrect? 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::forwardcorrect? 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