2016-11-22 6 views
1
として構造体を使用するためのベース

のは、私はこのような構造体があるとしましょう:C++ 11設定範囲は、要素

struct Something{ 
    string name; 
    int code; 
}; 

何か型のセット:

set<Something> myset; 
myset.insert({"aaa",123,}); 
myset.insert({"bbb",321}); 
myset.insert({"ccc",213}); 

これの何が問題なのですが?

for (auto sth : myset){ 
     cout << sth.name; 
     cout << sth.code; 
} 

同じような行を使って...(このセットにプレーンintアイテムが含まれている場合でも)このようなものを使用して、なぜ変更できないのですか?

for (auto &sth : myset){ 
     sth=[some value]; 
} 

私はベクトルと地図でこれを行うことができます。なぜセットはないの?

ありがとうございます!

答えて

1

セットの要素を変更すると、セットの順序でその位置が変わる可能性があることを意味します。コンパイラは、特定のセットがその要素の注文を決定するために正確に何を使用しているのかを知ることができないためです。理論的にはそうかもしれませんが、コンテナを反復しながら再編成を追跡することはほとんど不可能です。それは意味をなさないでしょう。

あなたができることは、セット内の順序を変更しないことがわかっている方法でセットの要素を変更したい場合は、構造体の順序付けられていないメンバーを変更可能にすることができます。間違えてセットの順序が乱れた場合、バイナリ検索のようなセット上の他の操作は、その誤った変更の後に不正確な結果をもたらすことに注意してください。メンバを変更可能にしたくない場合は、const_castもオプションで、同じ注意点があります。

#include <iostream> 
#include <set> 

struct bla 
{ 
    std::string name; 
    int index; 
}; 

bool operator<(const bla& left, const bla& right) { return left.index < right.index; } 

int main() 
{ 
    std::set<bla> example{{"har", 1}, {"diehar", 2}}; 

    // perfectly fine 
    for(auto b : example) 
    std::cout << b.index << ' ' << b.name << '\n'; 

    // perfectly fine - name doesn't influence set order 
    for(auto& b : example) // decltype(b) == const bla& 
    const_cast<std::string&>(b.name) = "something"; 

    // better than first loop: no temporary copies 
    for(const auto& b : example) 
    std::cout << b.index << ' ' << b.name << '\n'; 

    // using a "universal reference auto&&", mostly useful in template contexts 
    for(auto&& b : example) // decltype(b) == const bla& 
    std::cout << b.index << ' ' << b.name << '\n'; 

    // destroying order of the set here: 
    for(auto& b : example) 
    const_cast<int&>(b.index) = -b.index; 

    // anything here relying on an ordered collection will fail 
    // This includes std::set::find, all the algorithms that depend on uniqueness and/or ordering 

    // This is pretty much all that will still work, although it may not even be guaranteed 
    for(auto&& b : example) 
    std::cout << b.index << ' ' << b.name << '\n'; 
} 

Live code on Coliru


は、上記の私の答えに例を詳しく説明します。

最初のconst_castは、基本的にexampleconstではないため、okです。

+0

ありがとうございました!私は今参照してください。最初の部分はどうですか?私は要素を変更するのではなく、単に要素を読み込もうとしているだけで、構造体のメンバーであるということだけです。それはなぜ許されないのですか? –

+0

あなたは一定のauto&ofを使うことができるはずです。コピーを取ってもうまくいくはずですが... – rubenvb

+0

例を使って更新を見てください。 – rubenvb

関連する問題