10

を含むクラスstd::vector<Foo>です。FooFoo( Foo&& ) noexcept

コンテナーへのオブジェクトの追加は問題なく機能しますが、使用してそれらを消去することstd::vector::erase( iterator )はできません。GCC 4.7 は、削除した代入演算子を呼び出そうとします。正確なエラー メッセージは次のとおりです。

エラー: 削除された関数 'Foobar& Foobar::operator=(const Foobar&) の使用

編集:もちろんstd::vector、コピー コンストラクターではなく、代入演算子を呼び出します (エラー メッセージでも確認できます)。説明で修正しました、すみません。

要求されたソース コードの例を次に示します。

#include <vector>

class Foo {
    public:
        Foo() {}
        Foo( Foo&& other ) noexcept {}

        Foo( const Foo& ) = delete;
        Foo& operator=( const Foo& ) = delete;
};

int main() {
    std::vector<Foo> v;

    v.push_back( Foo{} );
    v.erase( v.begin() );
}
4

3 に答える 3

11

問題は、移動代入演算子を提供していないことです。これは、一部の関数のベクトル Movable 要件の一部です。

于 2012-09-28T09:54:14.993 に答える
2

再現できませんでした。良い習慣が大いに役立つことがわかりました。私は、移動割り当て演算子を定義しました。

GCC 4.7.2でのライブ:http://liveworkspace.org/code/36c600c285f2c91649fd4f73784c2c00

#include <iostream>
#include <vector>

struct Foo
{
    Foo() {}

    Foo(Foo const&) = delete;
    Foo(Foo&&) throw() { }

    Foo& operator=(Foo const&) = delete;
    Foo& operator=(Foo&&) throw() { return *this; }
};

int main(int argc, char* args[])
{
    std::vector<Foo> v;
    v.emplace_back();
    v.emplace_back();
    v.emplace_back();
    v.emplace_back();

    auto it = v.begin();
    it++;
    v.erase(it);
}
于 2012-09-28T09:48:17.770 に答える
1

DeadMG の回答は優れていますが、代入演算子の別の書き方を推奨したいと思います。

struct Foo {
    Foo() {}

    Foo(Foo const&) = delete;
    Foo(Foo&&) throw() { }

    Foo& operator=(Foo) throw() { return *this; }
};

メソッドの開始時に新しい一時が必要なため、コンパイラはコピーまたは移動コンストラクターのいずれかを選択して、この一時を独自に作成します。コピー代入演算子と移動代入演算子の両方を記述する必要はありません:)

于 2012-09-28T10:11:15.303 に答える