I have read a few posts about move functions (http://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html for example), and I wanted to observe move operators in action. So I tried the following code:
#include <vector>
#include <cassert>
#include <functional>
#include <algorithm>
#include <iostream>
using namespace std;
vector<double> operator+(const vector<double>& a, const vector<double>& b){
assert(a.size()==b.size());
vector<double> result(a.size(),0);
transform (a.begin(), a.end(), b.begin(), result.begin(), std::plus<double>());
cout<<&result<<endl;
return result;
}
int main(int argc, char const *argv[]) {
vector<double> a,b;
for (int i=0;i<10;i++){
a.push_back(i);
b.push_back(1);
}
std::vector<double> c=a+b;
cout<<&c<<endl;
return 0;
}
I was expecting to obtain the same address for the local variable result
and c
since move operators are implemented for vector
. And I obtained exactly that, but with and without the flag -std=c++11
. That is when I learned about NRVO (c++11 Return value optimization or move?), so I disabled it with the flag -fno-elide-constructors
and now the address is different, even with the flag -std=c++11
. Is there an issue with my code or did I understand something wrong about move operators ?
From what I understood, returning by value should be enough for the move operator to kick in (C++11 rvalues and move semantics confusion (return statement)).
PS: I tried with GCC 6.3.0_1 and Apple LLVM version 8.1.0 .
EDIT
As pointed out, I should have checked result.data()
instead of &result
(see below). But in that case, I always found the same address, even without std=c++11
and with -fno-elide-constructors
. See accepted answer and its comment section.
Think of a move as an optimized copy. It is still a copy, so it is still a different vector but it has "moved" the underlying data from one vector to the other. You can see that by comparing the address of the data:
cout<<result.data()<<endl;
and
cout<<c.data()<<endl;
Copy elision on the other hand eliminates the copy entirely.