問題タブ [value-initialization]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 異なる C++11 標準バージョンでデフォルト コンストラクターが削除されたクラスの初期化
重複では、少なくとも私の質問のポイント1と4に対する答えはありません。そして、それらは最も重要です。他の点は削除できますが、質問全体を閉じないようにお願いします。
1.以下のコードでは、obj1 が正常に作成されます。しかし、obj2 と obj3 の作成のコメントを外そうとすると、コンパイル (-std=c++11、g++ 4.9.2) は失敗します。なぜそうなのですか?オブジェクトのメモリがスタックに割り当てられているかヒープに割り当てられているかに関係なく、初期化は同じように実行する必要があると考えました。
2.標準に従って、2 種類の動作 (obj1-case または obj2,obj3-cases) のどちらが正しいかを理解しようとしました。標準では次のように述べられています (#3242 および #3337、8.5.4):
型 T のオブジェクトまたは参照のリスト初期化は、次のように定義されます。
— 初期化子リストに要素がなく、T が既定のコンストラクターを持つクラス型の場合、オブジェクトは値で初期化されます。
わかった。そこで、値の初期化の定義に進みます (#3242 および #3337、8.5.0):
T が (おそらく cv 修飾された) 非共用体クラス型であり、ユーザー提供のコンストラクターがない場合、オブジェクトはゼロで初期化され、T の暗黙的に宣言された既定のコンストラクターが自明でない場合、そのコンストラクターが呼び出されます。
(#3242, 12.1)によると
デフォルトのコンストラクターは、ユーザーが提供したものでも削除されたものでもない場合、自明です。. .
したがって、削除されたデフォルトのコンストラクターは自明ではないため、コードC obj1 { }; コンパイルに失敗するはずです。
しかし、(#3337、12.1)によると
デフォルトのコンストラクターは、それがユーザーによって提供されておらず、次の場合には自明です。. .
したがって、削除されたデフォルトのコンストラクターは、コードC obj1 { };の自明なものです。コンパイルに成功するはずです。
真実はどこにある?
3.しかし、それだけではありません。標準の次のバージョンでは、次のように述べられています (# 3367、8.5.4):
型 T のオブジェクトまたは参照のリスト初期化は、次のように定義されます。
— T が集合体の場合、集合体の初期化が実行されます
— それ以外の場合、初期化子リストに要素がなく、T が既定のコンストラクターを持つクラス型である場合、オブジェクトは値で初期化されます。
私が理解しているように、 Cは集約です。しかし、ここで問題があります。削除されたデフォルト コンストラクターを持つ集計がどのように作成されるかについての情報が見つかりませんでした。8.5.1 Aggregatesにはそのような情報はありません。しかし、これによると
8.5.4 で指定されているように、初期化子リストによって集合体が初期化されると、初期化子リストの要素は、添え字またはメンバーの昇順で、集合体のメンバーの初期化子として取得されます。各メンバーは、対応する initializer-clause からコピー初期化されます。. . (#3367、8.5.1)
[集約の場合にコンパイラで生成された]コンストラクターは、集約の初期化中に無視されるだけだと思います。したがって、削除されたデフォルトのコンストラクターも単純に無視され、C obj { };と推測できます。正常にコンパイルされるはずですが、デフォルトのコンストラクターが削除されたオブジェクトを作成するのは奇妙です。それでも、私が正しく理解していれば、このバージョンの標準 obj1-case によれば、大丈夫であり、obj2、obj3-cases がコンパイルに失敗するのは間違っています。私は正しいですか?
4.論理的な問題は、とにかく、どの標準バージョン #3242/#3337 または #3367 を信頼すべきかということです。バージョン #3367 は 2012 年に作成されたので 2011 年よりも遅く、c++11 と呼べるかどうかはわかりません。どのバージョンが真の C++11 標準と見なされますか? g++ 4.9.2 を使用して上記のコード例をコンパイルしました。コンパイラが使用する標準バリアントは何ですか? どうすれば知ることができますか? バージョン #3337 または #3367 が大きく異なるためです。
たとえば、#3367 では、値の初期化の定義が劇的に変更されました。
タイプ T のオブジェクトを値で初期化するとは、次のことを意味します。
— T が (おそらく cv 修飾された) クラス型 (第 9 節) であり、デフォルト コンストラクターがない (12.1) か、ユーザー提供または削除されたデフォルト コンストラクターのいずれかである場合、オブジェクトはデフォルトで初期化されます。
5.私の意見では、新しい値の初期化の定義は奇妙です。なぜなら、削除されたデフォルト コンストラクターを使用してオブジェクトを作成し、値を初期化できるケースが思いつかないからです。たとえば、 C クラスのint cメンバーをプライベートにすると、C クラスは式の集合体ではなくなります。
値の初期化 (以前のような集約の初期化ではない) [#3367, 8.5.4 "List-initialization"] になり、間違いなくコンパイルに失敗します。新しい値の初期化定義で削除されたコンストラクターについて説明していただけますか?
ここには多くのテキストがあることを理解しています。あなたがいくつか答えてくれたら、とても感謝しています。
c++ - デフォルトで初期化された (NOT 値/ゼロで初期化された) POD を右辺値として取得する
値を初期化せずA
に型の右辺値を渡すことは可能ですか? foo()
値の初期化または左辺値のいずれかを使用する必要がありますか?
10 ナノ秒以下の「コスト」で値の初期化を回避するポイントは何なのか、疑問に思うかもしれません。このような状況はどうでしょうか: valgrind による初期化されていないメモリ アクセスによって引き起こされるレガシー アプリのバグを探しており、ゼロはアプリの有効な値とは見なされません。値の初期化により、valgrind が初期化されていないメモリ アクセスの場所を特定できなくなります。
初期化されていない値を印刷することは UB であると言うかもしれませんが、私の「実際の」ユースケースは印刷に限定されません。私の質問はそれがなくても有効なままです。
c++ - ネストされたクラスの値の初期化
値の初期化の規則による。値の初期化が発生します。
1,5) 名前のない一時オブジェクトが空の括弧または中括弧のペアで構成される初期化子で作成された場合 (C++11以上);
2,6) 動的記憶域期間を持つオブジェクトが、括弧または中括弧の空のペアで構成される初期化子を持つ new 式によって作成される場合 (C++11以上)。
3,7) 非静的データ メンバーまたは基底クラスが空の括弧または中括弧のペアを持つメンバー初期化子を使用して初期化される場合 (C++11以上)。
4) 名前付き変数 (自動、静的、またはスレッドローカル) が、中かっこのペアで構成される初期化子で宣言されている場合。
些細な例
コンストラクターを明示的に宣言せずに、デフォルトのデフォルト ctor のままにしておきます // コンパイラーが生成したものを取得します。
ただし、別の構造体を使用しています。
ai の値は、ルールに反する {} / () 構造を使用しなくても、ゼロで初期化されます (私が間違っていない場合)。
構造体 B で同じロジックを使用する:
私たちはルールに従って行動します。
最後の例:
B().ai も、明示的にコンストラクターを宣言し、削除されていない間、ゼロで初期化されます。
これらの値がゼロで初期化されるのはなぜですか? ここに記載されている規則により、ゼロ初期化ではなくデフォルト初期化する必要があります。
回答ありがとうございます。
c++ - C++ 値は、カスタム コンテナーの項目を初期化します
vector
例としてカスタム実装を見てみましょう:
だから私の質問は、次のようにmyVector
初期化する場合に値を初期化する方法です。
ここでは、5 つint
の値が含まれているため、すべてゼロにする必要があります。他のタイプも同様。_buff[i] = 0;
特有のものなのでコメントアウトしましたint
。ヒントを教えてください。