2012-09-28 5 views
8

私はstd::vector<Foo>を持っています。FooFoo(Foo&&) noexceptを含むクラスです。std :: vector :: erase()は移動したくない

オブジェクトをコンテナに追加するのは完璧ですが、std::vector::erase(iterator)を使用してオブジェクトを消去しても、GCC 4.7は削除した代入演算子を呼び出そうとします。正確なエラーメッセージは次のとおりです。

エラー:削除された機能の使用「foobarの& FOOBAR ::演算子=(定数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()); 
} 
+1

デモコードはありますか? – kennytm

+0

コードがないと、問題の内容を確認するのが難しい – sehe

+0

ソースコードが追加されました。 :-) – stschindler

答えて

11

問題は、あなたが移動代入演算子を提供しなかったということです。これは、一部の機能のためのベクトルの可動性要件の一部です。あなたがメソッドの開始時に、新鮮な一時的に必要とするので

struct Foo { 
    Foo() {} 

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

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

、コンパイラはどちらか選択します:

+0

ああ。 Hehe。私は自分のサンプルを入力し、自動的に移動代入演算子を追加しました。それが私のために働いた理由を説明する:) +1 – sehe

+0

+1よく目撃された! – Walter

+1

コンパイラのエラーにより、それはすべて離れています - 適切な 'operator ='はありません。 – Puppy

2

私はそれを再現することができませんでした。良い習慣は遠くに行く:私は移動asignment演算子を定義していた。

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); 
} 
+0

実際には、 'erase()'はイテレータを好きではありませんが、 'std :: move_iterator <...>'に対応する関数呼び出しはありません。 – stschindler

+1

私はちょうど気づいて、コードを更新しました。複製サンプルを '発明する'ことで、@DeadMGが示唆するように、移動代入演算子を自動的に定義したことが判明しました。習慣... – sehe

+0

Hehe、面白いです。移動割り当て演算子も完璧な意味を提供してくれてありがとう。 – stschindler

1

DeadMGの答えは優れており、しかし私は、代入演算子を書いて別の方法を促進したいと思いますコピーまたは移動コンストラクタを使用してこの一時的なものを単独で作成し、コピー代入演算子と移動代入演算子の両方を記述する必要はありません:)

+0

彼のクラスはコピー不可能なので、彼はとにかくしません。 – Puppy

+0

@DeadMG:自動的にデフォルトに設定されているものと自動的に削除されるものの詳細を入力しないようにします...あまりにも奇妙です。 –

関連する問題