3

私は次のコードに従って、std :: mapを逆反復しようとしています:http ://www.cplusplus.com/reference/stl/map/rend/ それは言う:

rend()は、マップコンテナの最初の要素の直前の要素を参照する逆イテレータを返します。これは、その逆端と見なされます。

rendはbeginと同じ要素を参照するのではなく、その直前の要素を参照することに注意してください。

map<float,int> m;
m.insert(pair<float,int>(.1,0));
m.insert(pair<float,int>(.4,5));
map<float,int>::reverse_iterator rend=m.rend();
map<float,int>::iterator begin=m.begin();

これを実行すると、上記の通知を前提として、rendとbeginの両方がmの最初の要素(.1,0)を指しますが、明らかにそうすべきではありません。私が犯している非常に明白な間違いがあるように感じますが、それが何であるかを理解することはできません。

(C ++、MSVC2010)

4

3 に答える 3

3

あなたが見逃している点は、デバッガーを使用して値を調べると、rend()とによって返される値に同じ値begin() が含まれることだと思います。ただし、operator*イテレータ型のメンバーは、さまざまなオブジェクトへのアクセスを引き続き提供します。

技術的な詳細: によって返される値は、有効でないため、 のrend()前を指すことはできません。そのため、 には の値を含める必要があり、他のすべての逆反復子はさらに 1 位置シフトbegin()することが決定されました。はこれを補正し、とにかく正しい要素にアクセスします。rend()begin()operator*

24.5.1 逆反復子の最初の段落は次のように述べています。

クラス テンプレート reverse_iterator は、基になる反復子によって定義されたシーケンスの末尾からそのシーケンスの先頭まで反復する反復子アダプターです。逆反復子とそれに対応する反復子 i の間の基本的な関係は、次の恒等式によって確立されます
&*(reverse_iterator(i)) == &*(i - 1)

于 2012-04-21T19:47:40.543 に答える
2

rendが指している場所をどのように確認しているのかわかりませんが、この例を実行して、あなたの主張を反証しました.

int main() {

    map<float,int> m;
    m.insert(pair<float,int>(.1,0));
    m.insert(pair<float,int>(.4,5));
    map<float,int>::reverse_iterator rend=m.rend();
    map<float,int>::iterator begin=m.begin();

    for ( rend=m.rbegin() ; rend != m.rend(); rend++ )
    cout << rend->first << " => " << rend->second << endl;
}

出力:

0.4 => 5
0.1 => 0

が最初の要素を指している場合rend、0.1 => 0 は出力されません。

これは私の例です。red が最初の要素を指しているという結論に実際に到達したコードを示す必要があります。

于 2012-04-21T18:34:47.020 に答える
2

rendを指す要素へのアクセスは未定義の動作です。コンテナ内の最初のアイテムを取得したり、アプリケーションをクラッシュさせたり、想像できるものは何でもクラッシュする可能性があります。この要素は、反復時にコンテナーの終了を知らせるために使用される単なるプレースホルダーです (endさまざまな標準ライブラリ コンテナーにも同じことが当てはまります)。

于 2012-04-21T18:30:27.130 に答える