10

テスト目的で、小さな unordered_set を作成し、セットを反復しようとしました。セットは独自のクラスを保持します。

class Student {
private:
    int matrNr;
    string name;
public:
    Student( const int& matrNr = 0, const string& name = "" )
        : matrNr( matrNr ), name( name ) {}
    void setNr( const int& matrNr ) {
        this->matrNr = matrNr;
    }
...
};

いくつかの要素を挿入し、反復中にオブジェクトを変更しようとしました:

unordered_set<Student, meinHash> meineHashTable;
meineHashTable.emplace( 12, "Fred" );
meineHashTable.emplace( 22, "Barney" );
meineHashTable.emplace( 33, "Wilma" );

for (int i = 0; i < meineHashTable.bucket_count(); i++) {
    cout << "Bucketnummer: " << i << endl;
    unordered_set<Student, meinHash>::local_iterator iter;  // not constant?!?

    if (meineHashTable.bucket_size( i ) > 0) {
        for (iter = meineHashTable.begin( i ); iter != meineHashTable.end( i ); iter++) {
            //const_cast<Student&>(*iter).setNr( 1234 );  //This does work
            iter->setNr( 1234 );  //This does not work
        }

    }
    else {
        cout << "An empty Bucket" << endl;
    }

}

(const_local_iterator ではなく) local_iterator を使用しましたが、それでもオブジェクトを変更できません。何らかの理由で、反復子はまだ定数オブジェクトを参照しています。

私の質問:なぜそうなのですか?通常の反復子が const オブジェクトを参照する場合、const と非 const 反復子の違いは何ですか?

VisualStudio 2013 および minGW でテスト済み。

助けてくれてありがとう:-)

編集:ハッシュ関数:

struct meinHash {
    size_t operator()( const Student& s ) {
        return s.getNr();
    }
};

同じ質問をする将来このトピックの発見者のために、matrNrを暴力的に変更した場合の出力例を次に示します。

const_cast<Student&>(*iter).setNr( 5 );

それを表示してみてください:

unordered_set<Student, meinHash>::local_iterator iter = meineHashTable.find( 5 );
iter->display();

あなたは次のようなものを得るかもしれません:

バケット番号: 0

空のバケット

バケット番号: 1

マトリケル数: 5

名前:ヴィルマ

バケット数: 2

空のバケット

バケット数: 3

空のバケット

バケット数: 4

マトリケル数: 5

名前:フレッド

バケット数: 5

空のバケット

バケット数: 6

マトリケル数: 5

名前:バーニー

バケット数: 7

空のバケット

//不要な出力 ;-)

マトリケル番号: -842150451

名前:

4

5 に答える 5

7

a の値の型はset<K>isconst Kであり、 a のmap<K, T>場合は it ispair<const K, T>です。順序付けられていないバージョンについても同様です。

イテレータは へのアクセスを提供しvalue_type &、const-iterator は へのアクセスを提供しますconst value_type &。ご覧のとおり、どちらのイテレータ型もキーの constness を「元に戻す」ことはできません。

キーが不変である理由は、基になるデータ構造の不可欠な部分を形成するためです。キーを変更すると、あらゆる種類の問題を引き起こす自明ではない内部再配置が必要になります (たとえば、ゼロでない計算の複雑さ (要素アクセスのため!) やイテレータの順序の混乱)。

于 2013-09-09T18:06:05.547 に答える
1

unordered_set は、場所を変更せずに項目を変更できない一種のデータ構造です。

非定数イテレータは、ここでは const です。STL は、このような明らかな間違いからあなたを守ってくれるからです。

unordered_set の項目を変更したい場合は、それを削除して再度追加する必要があります。

于 2013-09-09T18:04:38.350 に答える