8


1

vector.resize()メソッドは、サイズ変更時にデフォルトの要素コンストラクターを呼び出しますか?

私は次のコードを試しています。

struct _Struct2
{
    void   *ptr;
    double dval;
};

struct _Struct
{
    float fval;
    int   ival;
    std::vector<_Struct2>   data;
};

std::vector<_Struct>    vec;


int main()
{
    vec.resize( 9 );
    for ( int i = 0; i < vec.size(); i++ )
    {
        _Struct &elem = vec[i];
        int     len = elem.data.size(); // elem.data is [0]()
    }
}
resize(9)は、_Struct型の9つの要素を割り当てる必要があります。 そして、実際には機能します。 ただし、タイプ_Structのすべての要素、特に別のstd

vectorであるデータ要素は初期化されません。 空のstd :: vectorに初期化してほしい。 手動で行う必要がありますか? resize()メソッドは、すべての_Struct要素のデフォルトコンストラクターを呼び出すと考えました。 Thx

Ps. ここで使用されている構造体の名前は、私の頭に浮かぶ最初のものです。 これはほんの一例です。 Visual Studioは、elem.dataがデバッグビューで `[0]()`に対応することを教えてくれます。

Ps. `[0]()`を忘れてください。

1 Answer


18


いいえ、デフォルトの要素コンストラクターを呼び出しません。 `std

vector`はデフォルトのコンストラクターを内部的に呼び出すことはありません(C ++ 11で呼び出しますが、以前のバージョンの仕様では呼び出しません)。

`vector

resize`の完全な署名は次のようになります

void resize(size_type sz, T c = T());

I.e. 2番目のパラメーター(デフォルトの引数値)があります。 次に、その2番目のパラメーターを「ソース」オブジェクトとして使用して、_copy-constructor_によって新しい要素を初期化します。

言い換えれば、 `resize`の呼び出しは実際には

vec.resize( 9, _Struct() );
つまり、「source:」オブジェクトを `vector

resize`に指定したときにデフォルトのコンストラクターを呼び出したのは_you_でした。

_ ただし、タイプ_Structのすべての要素、特に別のstd :: vectorであるデータ要素は初期化されません。 _

Huh? 「初期化されていません」? サンプルコードで、 resize`によって作成されたすべての新しい要素が上記のように完全に初期化されることを考えると、それが何を意味するのかわかりません。暗黙的に提供された _Struct() 要素からコピー初期化2番目の引数として `resize。 それぞれの `_Struct

fval`と` _Struct :: ival`はゼロで、それぞれの `_Struct :: data`は空のベクターです。

(元のC ++ 98では、 `_Struct

fval`と` _Struct :: ival`は初期化されません。TC1以前のC 98は_value-initialization_をサポートしていなかったためです。 しかし、元のC 98であっても、 `_Struct :: data`は空のベクターに初期化されます)。

_ 空のstd :: vectorに初期化してほしい。 _

すべての `_Struct

data`ベクトルはすでに空のベクトルとして初期化されています。 そうではないと思わせたのはなぜですか?

P.S. `_`で始まり、その後に大文字が続く名前は、実装によって予約されています。 それらの使用は許可されていません。