便利なんですが、巡回先のコレクションから受け側の変数に代入されるだけなので、参照で受けないとコピーされます。
以下のような、テスト用にコンストラクタ・デストラクタでprintfするだけの適当なクラスがあるとして。
class Hoge { public: Hoge() { printf("ctor %p\n", this); } Hoge(const Hoge& h) { printf("copy %p\n", this); } ~Hoge() { printf("dtor %p\n", this); } };気を使わずに単に変数で受けて巡回すると…
vector<hoge> hoge_vector(3); BOOST_FOREACH(Hoge x, hoge_vector) { ; }
ctor 0x20010210 ctor 0x20010211 ctor 0x20010212 copy 0x28ac26 dtor 0x28ac26 copy 0x28ac26 dtor 0x28ac26 copy 0x28ac26 dtor 0x28ac26 dtor 0x20010210 dtor 0x20010211 dtor 0x20010212ですよねー。参照(&x)で受けないと、スタック上にコピーして破棄してを繰り返しています。関数の引数でオブジェクトを値渡し、みたいな話でちょっと恥ずかしい。 boost.org公式のドキュメントにも、"Iterate over a sequence by reference, and modify the underlying sequence" という例が書いてあります。
参考:公式ドキュメント
参照で受ければ、もちろんコピーされずに済みます。
BOOST_FOREACH(Hoge &x, hoge_vector) { ; }
ctor 0x20010210 ctor 0x20010210 ctor 0x20010211 ctor 0x20010212 dtor 0x20010210 dtor 0x20010211 dtor 0x20010212こんなくだらない話ですが、autoを使おうとするときって、型に対する意識が散漫になりませんか?
BOOST_FOREACH(auto x, hoge_vector) { ; } // コピーされるよ BOOST_FOREACH(auto &x, hoge_vector) { ; }このループで変更を加えようとしている場合には、一時的に複製されたものを触っても何もおきなくて気づきます。しかし、読むだけの場合にはロジック上の不都合は起きないので、うっかりこのようなコードを埋め込んでしまうかも。
# boost 1.48.0にて確認
0 件のコメント:
コメントを投稿