aliasを使ってみる & boost::assign は N個追加するのにO(N^2)のコピーをするのか?

何かコピーが重たいオブジェクトのvectorがあったとする(名前はmatrix)。これのi番目について何度も処理をするときにいちいちmatrix[i]って書くのは面倒だし読みにくいし。ここは「line」みたいな別名をつけたい。


Pythonだと、変数は根本的に参照なので line = matrix[i] でいいわけなのだけど、C++でこれをやるとmatrix[i]の内容をコピーしてしまうので重たい。C++で必要もなくポインタを使うのはCで必要もなくgotoを使うようなものだと思っていたのでこの前Single Round Match 407 - 西尾泰和のはてなダイアリーではなんとかポインタを避けようと四苦八苦した上で結局ポインタを使ったのだった。


しかし、C++プライマーを読んでたら「参照型」なんてのがあるって書いてある!

int main(){
  vector<MyValue> maxtix;
  matrix += MyValue(1), MyValue(2), MyValue(3);
  MyValue &line = matrix[1]; 
  cout << line.value << endl;
}

おおー、求めていたのはこれだ!いちおう、これで「&line = matrix[i]」でコピーが起きないことを確認しよう。

int main(){
  vector<MyValue> matrix;
  matrix += MyValue(1), MyValue(2), MyValue(3);
  cout << "start assgin" << endl;
  MyValue &line = matrix[1];
  cout << "end assgin" << endl;
  cout << line.value << endl;
}
//----- 実行結果 -----
cstr 3
cstr 2
cstr 1
copy cstr 1
copy cstr 1
copy cstr 2
copy cstr 1
copy cstr 2
copy cstr 3
copy cstr 1
copy cstr 2
copy cstr 3
start assgin
end assgin
2

ちょっ。参照型への代入は確かにコピーが起きてないんだけど、boost::assignがいっぱいコピーしている><

// matrix += MyValue(1);
cstr 1
copy cstr 1
copy cstr 1

// matrix += MyValue(1), MyValue(2);
cstr 2
cstr 1
copy cstr 1
copy cstr 1
copy cstr 2
copy cstr 1
copy cstr 2

// matrix += MyValue(1), MyValue(2),  MyValue(3), MyValue(4);
cstr 4
cstr 3
cstr 2
cstr 1
copy cstr 1
copy cstr 1
copy cstr 2
copy cstr 1
copy cstr 2
copy cstr 3
copy cstr 1
copy cstr 2
copy cstr 3
copy cstr 4
copy cstr 4 <- ん?

// 5
cstr 5
cstr 4
cstr 3
cstr 2
cstr 1
copy cstr 1
copy cstr 1
copy cstr 2
copy cstr 1
copy cstr 2
copy cstr 3
copy cstr 1
copy cstr 2
copy cstr 3
copy cstr 4
copy cstr 4 <- むむ?
copy cstr 5 <- なんだこれ?
copy cstr 1
copy cstr 2
copy cstr 3
copy cstr 4
copy cstr 5

眠い頭ではわからない謎。