2013-07-11 5 views
12

このコードは、私を混乱させる:std :: mapのキー/値タイプの要件をコピー/移動しますか?

struct foo { 
    int i; 

    foo(int j) : i(j) {} 

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

bool operator<(const foo &f1, const foo &f2) 
{ 
    return f1.i < f2.i; 
} 

int main(int argc, char **argv) 
{ 
    std::map<foo,int> f; 
    std::map<foo,int> f2 = f; //error (as expected) 
    std::map<foo,int> f3 = std::move(f); //no error (why?) 
    return 0; 
} 

私はそこには、エラーを取得していないので、それは(いなくても、そこに別のキーオブジェクトを移動するための)どのキーオブジェクトが作成されていないマップを移動するときのように思えます。

どうしてですか? C++ 11標準に従ってこの動作に頼ることができますか?

は、より一般的には、どのようなコピー/要件を移動すると、キーと値の種類とどのような条件の下でstd::map場所のでしょうか?

+0

地図を移動すると_no_要件がキーと値に配置されます。 –

+1

@MooingDuck、アロケータのタイプが –

+0

ああ伝播しない場合はそうではありません。アロケータはすべてを混乱させる可能性があります。 –

答えて

14

マップを別のマップにコピー割り当てするには、各アイテムをコピーする必要があります。アイテムをコピーすることはできないので、マップをコピー・アロケートすることはできません。これらは純粋タイプオブジェクトのによって完全に決定静的考慮事項であるので、実際の地図オブジェクトは、実行時に空であるかどうか

は、重要ではありません。容器はノードベースと実際のであるため、全体地図を移動

(これは明らかに、結果が整数である場合sin(0)は、浮動小数点ユニットを必要とする理由を尋ねるようなものだ。)

は、一方で、結構です値は突然変異し、ノードだけが突然変異する。実際、ノードベースのコンテナの移動構築または移動割り当ては、要素がコピー可能である必要はありません。または可動またははすべて割り当て可能です。

(これは、std::allocator<value_type>などを介して適切な方法で動的メモリを管理するすべてのコンテナのために真でなければなりませんが、それはもちろんstd::arrayのようなもののために真実ではないであろう、そして開催するか否かの興味深いものになるだろう割り当て方式は、ノードの卸売を移動することができる。)でない場合にのみmapが移動するのでstd::dynarrayため、@ジョナサンWakelyが述べているように、

+4

'M'型のマップを移動割り当てするには、' allocator_traits :: propagate_on_container_move_assignment :: value'がfalseの場合、要素タイプを 'MoveInsertable'から' M'にする必要があります。 –

+0

@JonathanWakely:はい、それは非常に良い点です。それはすべてアロケータに依存します! –

+3

気をつけてください。 - \ –

3

mapのない要素、エラーありません。要素へのポインタだけが割り当てられます

関連する問題