25

私は次のコードを持っています

class A {
    public:
        A(){}
        ~A(){}
    private:
        std::vector<std::unique_ptr<double> > x;
};

A f() {
    A a;
    return a;
}

int main() {
    A a=f();
    return 0;
}

デストラクタをコメントアウトしない限り、コンパイルされません(gcc 4.7)。実際、コードにこのデストラクタは必要ありません。デバッグ目的で使用したかっただけです。

しかし、何が起こっているのかわからないので、何か間違ったことをしたのではないかと心配しています。ここで何が起きてるの ?

4

1 に答える 1

31

これは、明示的に定義されたデストラクタが存在すると、 のムーブ コンストラクタの暗黙的な生成が妨げられるためAです。

C++11 標準のパラグラフ 12.8/9 によると:

クラス X の定義でムーブ コンストラクターが明示的に宣言されていない場合、1 つが暗黙的にデフォルトとして宣言されます。

— X にはユーザー宣言のコピー コンストラクターがありません。

— X には、ユーザー宣言のコピー代入演算子がありません。

— X には、ユーザーが宣言した移動代入演算子がありません。

X にはユーザー宣言のデストラクタがなく、かつ

— 移動コンストラクターは暗黙的に削除済みとして定義されません。

移動コンストラクターがない場合f()、コンパイラーから値を返すために、暗黙的に生成されたコピー コンストラクター (下位互換性のためにまだ生成されています) を呼び出そうとします。ただし、std::unique_ptrコピペ不可。したがって、エラー。

ムーブ コンストラクターを明示的に定義する (または、コメントでjuanchopanzaが提案しているように、コンストラクターをデフォルトとして宣言する) と、問題が解決します。

于 2013-03-18T20:06:12.663 に答える