次のように書く代わりに、
class A {
public:
A(A&&) noexcept = default;
};
書くべきなのは
class A {
public:
A(A&&) noexcept;
};
inline A::A(A&&) noexcept = default;
私が聞いた理由は次のとおりです。
コンストラクタが になることを回避します
deleted
。関数を定義できない場合、コンパイラはエラーを出します。noexcept
一部のメンバー フィールドの移動コンストラクターに の注釈が付いていない場合でも、移動コンストラクターは宣言されますnoexcept
。
誰か、その違いの背後にある理論についてもう少し詳しく説明してくれませんか?
ベストアンサー1
クラス/メソッドを記述するには宣言のみを使用するので、
class A {
public:
A(A&&) noexcept;
};
A::A(A&&)
必要に応じて実装することもできます(定義は異なるTUにすることができます)
次のように実装すると:
A::A(A&&) noexcept = default;
コンパイラはメソッドを生成する必要があります (宣言された正確なメソッドが存在するため、暗黙的に削除されるかどうかを判断できません)。生成できない場合は診断を提供します。
しかし、クラス内で宣言すると次のようになります。
class A {
public:
A(A&&) noexcept = default;
};
これは宣言の「一部」です。そのため、暗黙的に削除される可能性があります (メンバーまたは基本クラスが原因で)。
も同様に適用されますnoexcept
。
専用の TU に定義を配置するもう 1 つの利点は、必要な依存関係の定義が、メソッドが生成される各場所ではなく、その TU にのみ配置できることです (たとえば、pimpl イディオムに役立ちます)。
定義と宣言を分割することの 1 つの欠点は、メソッドが「ユーザー提供」になり、trivially_constructible/copyable/... などの特性に影響する可能性があることです。