プライベート コンストラクターと集合体初期化: 予期しない相互作用
C では、デフォルト コンストラクターをプライベートとして宣言すると、当然、関連する型のデフォルトの構造にアクセスできなくなります。ただし、中括弧で囲まれた初期化構文を使用すると、特有の動作が発生します。
次の例を考えてみましょう:
class C { C() = default; }; int main() { C c; // error: C::C() is private auto c2 = C(); // error: calling a private constructor }
予想外に、上記のコードはすべての主要なコンパイラでエラーを生成します。デフォルトのコンストラクターは実際にプライベートとして宣言されているため、これは予期された動作です。ただし、中括弧で囲まれた初期化を使用すると、突然デフォルトの構築が可能になります:
int main() { C c{}; // OK auto c2 = C{}; // OK }
この予期しない動作の背後にある理由は、C 標準ライブラリの複雑さにあります。 C 14 標準 (8.4.2/5) によれば、関数がユーザーによって宣言され、最初の宣言で明示的にデフォルト設定または削除されていない場合、その関数は「ユーザー提供」とみなされます。
の場合上記の C クラスでは、デフォルト コンストラクターは最初の宣言で明示的にデフォルト設定されます。これは、「ユーザー提供」とみなされないことを意味します。その結果、C クラスにはユーザー提供のコンストラクターがなく、8.5.1/1:
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).
の定義に従って集約になります。その結果、C クラスでは中括弧で囲まれた初期化が許可されます。クラス。コンストラクターがプライベートとして宣言されている場合でも、デフォルトの構築が可能です。この動作は驚くべきものであり、特定のシナリオでは望ましくない結果につながる可能性があります。
以上がプライベートのデフォルト コンストラクターを使用して集計を初期化できるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。