STLコンテナのランダムアクセスイテレータの興味深いロジック

プログラミングコースでは、C ++でstd :: vectorの類似物を作成し、機能とインターフェイスを保存して、100万倍以上読みやすくするためのタスクを取得しました。 実行中に、ランダムアクセスイテレータには、変更したい非常に奇妙な興味深い機能があることに気付きました。 誰が気にします-猫へようこそ。



イテレータについて簡単に


Habréのイテレーターに関する優れた記事はすでにここにあります

私自身は、Wikipediaのイテレーターに関する記事の定義のみを追加したいと考えています。

イテレータは、単一のインターフェースの背後にあるコレクションの要素へのアクセスを抽象化するオブジェクトです。

イテレーターを作成する


したがって、2つの整数ベクトルを作成します。

vector<int> vector1; vector<int> vector2;
      
      





0から14までの両方の数値を入力します。

  for ( int i = 0; i < 15; i++ ) { vector1.push_back(i); vector2.push_back(i); }
      
      





各ベクトルの反復子を作成します。

  vector<int>::iterator it1 = vector1.begin(); vector<int>::iterator it2 = vector2.begin();
      
      





実際に興味深い機能


最初に私を驚かせたのは、2つのイテレータに対してオーバーロードされた演算子「-」の存在とオーバーロードされた演算子「+」の不在です(intでイテレータを追加します)。 最初のベクトルに追加のイテレータを作成し、両方のアクションを実行します。

  vector<int>::iterator temp = vector1.begin() + 3; cout << temp - it1 << endl; <s> cout << temp + it1 << endl;</s>
      
      





前者の場合、出力3、2番目の場合-コンパイルエラーが発生します。



第二に、反復子の平等の問題に興味がありました。 定義に基づいて、イテレータはコレクションの要素へのアクセスを提供する必要があります。 つまり、2つのイテレータが異なるコレクションに属している場合、キャップはそれらをまったく比較できないことを示します。 ただし:

  if ( it1 == it2 ) { cout << "Equal" << endl; } else { cout << "Not equal" << endl; }
      
      





出力は「等しくない」です。これは、そのような比較の可能性が非常に奇妙であるため、非常に論理的です。

異なるオブジェクトのイテレータを比較することが可能であることに気付いた後、私は一方を他方から差し引くことを試みることにしました:

  cout << it1 - it2 << endl;
      
      





出口で34を得ます。私はすぐにペレビンと彼の「数字」を思い出しました。

簡単な要約
Pelevinの新しい小説「Numbers」のヒーローは、Stepanのビジネスマンです。 幼少期でさえ、ストーパは自分が他の人とは違うことに気づきました。 Styopaは、7番には不可解な潜在的な渇望を感じていましたが、非常に多くの才能のある人々が崇拝しているこの素晴らしい数を喜ばせる方法を理解していませんでした。 その結果、彼は7が3 + 4に過ぎないことに気付きました(これについては後で説明します)ので、彼は34番を崇拝し始めました。

pelevin.nov.ru/stati/o-lleo2/1.htmlから取得



出力で予測不可能なintを取得するという事実は、ベクトルが互いに相対的にメモリ内に配置される方法に関連しています。 両方のベクトルに異なる数の数値を入力しようとすると、まったく異なる結果が得られました。



まあ、最も興味深い:

  it2 += 34; if ( it1 == it2 ) { cout << "Equal" << endl; } else { cout << "Not equal" << endl; }
      
      





出口では、ご想像のとおり、等しいです。 これは次の結論につながります。これは私の観点からは好ましくありません。

  it2 = vector2.begin() + 34;
      
      





は、2番目のベクトルではなく、最初のベクトルを繰り返すことができます。



結論


ランダムアクセスイテレータを作成するとき、開発者は、イテレータの使用を、それが作成されたコンテナのスコープに制限しませんでした。 個人的には好きではありませんが、私は彼らの論理を理解できます。 異なるベクトルを指す反復子の厳密な比較と減算はそれほど難しくありません。 そして、おそらく、そのような状況はまれですが、これらの機能を忘れないでください。



All Articles