私は移動機能(例えばhttp://www.cprogramming.com/c++11/rvalue-references-and-move-semantics-in-c++11.html)についていくつかの記事を読んでいます。だから私は、次のコードを試してみました:C++ - NRVO and move
#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;
}
私は移動演算子がvector
のために実装されているので、ローカル変数result
とc
に同じアドレスを取得するために期待していました。そして私は正確にそれを得ましたが、フラグがある場合とない場合-std=c++11
。それがNRVO(c++11 Return value optimization or move?)について学んだので、私はフラグ-fno-elide-constructors
でそれを無効にしました、そして今、アドレスは-std=c++11
であっても異なっています。私のコードに問題はありますか、または移動オペレータについて間違ったことを理解しましたか?
私が理解したところでは、値を返すことは、移動オペレータが(C++11 rvalues and move semantics confusion (return statement))を開始するのに十分でなければなりません。
PS:GCC 6.3.0_1とApple LLVMバージョン8.1.0を試しました。
EDIT
としては、私は(下記参照)result.data()
の代わり&result
をチェックしているはず、と指摘しました。しかし、その場合は、std=c++11
と-fno-elide-constructors
がなくても、私はいつも同じアドレスを見つけました。受け入れられた回答とそのコメントセクションを参照してください。
すぐにお返事ありがとうございます。私は 'data'で試してみました。しかし、私は '-fno-elide-constructors'と' -std = C++ 11 'を使わないで同じアドレスを取得します。奇妙なんじゃない?どのようにして、コンパイラは、コピー・エリートと移動演算子を使用せずに最適化できますか? –
@PierreMarchandあなたの質問では、 '-fno-elide-constructors'はいつも別のアドレスを与えたと言いました(私が期待しているもの) –
@MM私は彼らが' .data() 'のアドレスを参照していると思います –