1. ホーム
  2. c++

[解決済み] C++11の新しい構文「= default」について

2022-03-07 18:48:22

質問

なぜ、こんなことをするのか理解できない。

struct S { 
    int a; 
    S(int aa) : a(aa) {} 
    S() = default; 
};

と言えばいいのでは。

S() {} // instead of S() = default;

なぜ新しい構文を持ち込むのか?

どのように解決するのですか?

デフォルト化されたデフォルトコンストラクタとは、具体的には、初期化リストがなく、複合文が空であるユーザー定義のデフォルトコンストラクタと同じものであると定義されています。

§12.1/6 [クラス.コンテナ] を参照してください。 defaulted であり deleted と定義されていないデフォルトコンストラクタは、そのクラス型のオブジェクトを作成するために odr-used されたとき、または最初の宣言の後に明示的に defaulted されたときに暗黙的に定義されます。暗黙的に定義されたデフォルトコンストラクタは,ctor-initializer (12.6.2) がなく,空の複合文のあるそのクラスに対してユーザが書いたデフォルトコンストラクタが実行するであろうクラスの初期化集合を実行する。[...]

しかし、どちらのコンストラクタも同じ動作をしますが、空の実装を提供すると、クラスのいくつかのプロパティに影響を与えます。ユーザー定義のコンストラクタを指定すると、何もしないにもかかわらず、その型が アグリゲート でなく、また トリビアル . クラスを集約型やトリビアル型(あるいは推移性によって POD 型)にしたい場合は,以下のようにします. = default .

§8.5.1/1 [dcl.init.aggr]の項参照。 集約は、ユーザーが提供するコンストラクタを持たない配列またはクラスで、[and...]です。

<ブロッククオート

§12.1/5 [クラス.コンテナ]編 デフォルトのコンストラクタは、ユーザが提供するものでなければ些細なものであり、[...]です。

§9/6 [クラス]の場合 つまらないクラスとは、つまらないデフォルトコンストラクタと [...] を持つクラスのことです。

実証すること。

#include <type_traits>

struct X {
    X() = default;
};

struct Y {
    Y() { };
};

int main() {
    static_assert(std::is_trivial<X>::value, "X should be trivial");
    static_assert(std::is_pod<X>::value, "X should be POD");
    
    static_assert(!std::is_trivial<Y>::value, "Y should not be trivial");
    static_assert(!std::is_pod<Y>::value, "Y should not be POD");
}

さらに、コンストラクタを明示的にデフォルトにすることで、それを constexpr を指定すると、暗黙のコンストラクタが持っていたのと同じ例外仕様が与えられます。この例では、暗黙のコンストラクタは constexpr (データメンバを初期化しないままにしてしまうため)また、例外の仕様も空になってしまうので、違いはありません。しかし、そうです、一般的なケースでは、手動で constexpr と例外仕様が暗黙のコンストラクタに一致するようにします。

使用方法 = default は、コピー/ムーブコンストラクタとデストラクタでも使用できるため、ある程度の統一性をもたらします。たとえば、空のコピー コンストラクタは、デフォルトのコピー コンストラクタ(メンバ単位でコピーを実行する)と同じことはできません。このため = default (または = delete という構文に統一することで、コードを読みやすくすることができます。