2017-02-06 3 views
7
#include <vector> 
struct S { int x; }; 
std::vector<S> v; 
int main() { v.resize(1000); return v[42].x; } 

上記のプログラムは、C++ 14で0を返すことは保証されていますか?どうして?プリミティブ型を含む構造体のコンテナ、ゼロが初期化されていますか?

+0

[クラス内のすべての2倍をゼロに初期化する]の可能な複製(http://stackoverflow.com/questions/42010793/initializing-all-doubles-in-a-class-to-zero) – SU3

答えて

3

std::vector::resizeと同様の方法を順番に凝集体のメンバ値が初期化†デフォルトによって値の初期化を実行するためはい:cppr:

値の初期化の効果

から

である:
[...]
Tが、ユーザー提供も削除もされないデフォルトのコンストラクタを持つクラス型である場合(つまり、暗黙的に定義されたクラスまたはデフォルトのdのデフォルトコンストラクタ)、オブジェクトはゼロで初期化され、デフォルトのコンストラクタでない場合はデフォルトで初期化されます。

Zero Initialiation部分は、私たちが必要なものを行います。

Tは、非組合クラス型である場合は、すべての基底クラスと非静的データメンバは、ゼロ初期化され、すべてのパディングが初期化されます0ビットにする。コンストラクタがあれば、無視されます。

そしてもちろん、私たちのメンバーのゼロ初期化が正しいことない:Tはスカラー型である場合は、オブジェクトの初期値を明示的にT.

に変換する整数定数ゼロ

です


デフォルトのアロケータは、カスタムアロケータが異なる初期化を使用することがあります。そのような値をユニット化したままにすることができます。詳しくはdefault-insertをご覧ください。

3

上記のプログラムは、C++ 14で0を返すことは保証されていますか?どうして?

はい。 [vector.capacity]から:

void resize(size_type sz);
13効果sz < size()場合は、シーケンスから最後size() - sz要素が消去されます。それ以外の場合は、sz - size()がデフォルトで挿入された要素をシーケンスに追加します。それはpでのアドレスである式allocator_traits<A>::construct(m, p)の評価によって初期化されている場合

Xの要素は、デフォルト挿入である:[container.requirements.general]から、

X内に割り当てられた要素の初期化されていない記憶域。std::allocator<T>ため

construct [default.allocator]から、行います

template <class U, class... Args> 
void construct(U* p, Args&&... args); 

効果::new((void *)p) U(std::forward<Args>(args)...)

だから、それは価値の初期化です。我々はnew S()であり、new Sではないので、メンバーxはゼロで初期化されます。この現象を回避する


方法は(必要な場合)のいずれかである:

  1. 変更アロケータ。 constructの2つのオーバーロードを持つ独自のアロケータ・タイプを提供します.1つは空(デフォルト初期化を行います)、もう1つはArgs&&...です。
  2. 種類を変更します。初期化を行わないデフォルトコンストラクタをSに追加します。
関連する問題