hoge diary - February 6, 2006

[C++] std::vector の実装

以下のソースをコンパイル,実行してみると,コピーコンストラクタが 4 回呼び出されているのを確認できました.

#include <iostream>
#include <vector>

class A
{
public:
    A()                    { std::cerr << "A default ctor" << std::endl; }
    A(const A& s)          { std::cerr << "A copy ctor" << std::endl; value_ = s.value_; }
    int value_;
};

int main()
{
    std::vector<A> a1;
    std::vector<A> a2;

    std::cerr << "a1.resize(4)..." << std::endl;
    a1.resize(4);

    std::cerr << "a2.reserve(4)..." << std::endl;
    a2.reserve(4);

    return 0;
}
% g++ -O0 test.cc
% ./a.out
a1.resize(4)...
A default ctor
A copy ctor
A copy ctor
A copy ctor
A copy ctor
a2.reserve(4)...
%

memcpy() 等を使ってメモリイメージを丸ごとコピーしているわけではないことがわかりましたが... コピーコンストラクタが 3 回ではなく 4 回呼ばれています.vector の最初の要素は 2 回のコンストラクタ呼び出しによって初期化されているのでしょうか.

ちなみにこの挙動は,無償版の icc 6.0.031 を用いても確認することができました.コンストラクタでは初期化以外の処理をしないほうが良さそうです.

コメント

(posted on: Sat Feb 25 00:48:11 JST 2006)

なぜまずソースを当たらないのか。template なんだからヘッダファイルを覗くだけなのに…。

      void
      resize(size_type __new_size) { resize(__new_size, value_type()); }

      void
      resize(size_type __new_size, const value_type&amp; __x)
      {
        if (__new_size &lt; size())
          erase(begin() + __new_size, end());
        else
          insert(end(), __new_size - size(), __x);
      }

更に言うと,ISO/IEC14882:1998 には:

void resize(size_type sz, T c = T());
Effects:
  if (sz &gt; size())
    insert(end(), szsize(), c);
  else if (sz &lt; size())
    erase(begin()+sz, end());
  else
    ; //do nothing

と書かれているので明白。

pakuchan (posted on: Wed Mar 08 00:54:42 JST 2006)

&gt; template なんだからヘッダファイルを覗くだけなのに
確かにその通りです.書きっぱなしにしていました.フォローに感謝します.

ヘッダファイルを調べた結果,件の疑問は解決しました.
この話のまとめは
  http://www.pakunet.jp/hoge/2006/3/7#article1
に書きました.

検索エンジン等でここを参照されている方は,上の URI のリソースも必要に応じて参照してください.

名前(何でも可):

テキスト(http:// を含む内容は投稿できません):

トラックバック

トラックバック URI: https://www.pakunet.jp/hoge/trackback/2006020601

トラックバックはありません.


Valid XHTML 1.1! Valid CSS!
© 2004-2009 ぱくちゃん.
Last modified: Fri Nov 02 08:58:03 JST 2007