#include <vector>
struct S { int x; };
std::vector<S> v;
int main() { v.resize(1000); return v[42].x; }
上記のプログラムは、C++ 14で0を返すことは保証されていますか?どうして?プリミティブ型を含む構造体のコンテナ、ゼロが初期化されていますか?
#include <vector>
struct S { int x; };
std::vector<S> v;
int main() { v.resize(1000); return v[42].x; }
上記のプログラムは、C++ 14で0を返すことは保証されていますか?どうして?プリミティブ型を含む構造体のコンテナ、ゼロが初期化されていますか?
std::vector::resize
と同様の方法を順番に凝集体のメンバ値が初期化†デフォルトによって値の初期化を実行するためはい:cppr:
値の初期化の効果から
である:
[...]
Tが、ユーザー提供も削除もされないデフォルトのコンストラクタを持つクラス型である場合(つまり、暗黙的に定義されたクラスまたはデフォルトのdのデフォルトコンストラクタ)、オブジェクトはゼロで初期化され、デフォルトのコンストラクタでない場合はデフォルトで初期化されます。
とZero Initialiation部分は、私たちが必要なものを行います。
Tは、非組合クラス型である場合は、すべての基底クラスと非静的データメンバは、ゼロ初期化され、すべてのパディングが初期化されます0ビットにする。コンストラクタがあれば、無視されます。
そしてもちろん、私たちのメンバーのゼロ初期化が正しいことない:Tはスカラー型である場合は、オブジェクトの初期値を明示的にT.
に変換する整数定数ゼロです
†デフォルトのアロケータは、カスタムアロケータが異なる初期化を使用することがあります。そのような値をユニット化したままにすることができます。詳しくはdefault-insertをご覧ください。
上記のプログラムは、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
はゼロで初期化されます。この現象を回避するの
方法は(必要な場合)のいずれかである:
construct
の2つのオーバーロードを持つ独自のアロケータ・タイプを提供します.1つは空(デフォルト初期化を行います)、もう1つはArgs&&...
です。S
に追加します。
[クラス内のすべての2倍をゼロに初期化する]の可能な複製(http://stackoverflow.com/questions/42010793/initializing-all-doubles-in-a-class-to-zero) – SU3