デリファレンスとインクリメント
メニューを表示するにはスワイプしてください
イテレータは、参照外し演算子(*)を使用して、ポインタと同様に指している値へアクセスします。要素がオブジェクトの場合は、メンバーアクセス演算子(->)を使うことで、そのメンバーにアクセスできます。
イテレータはインクリメント演算子で進めます。前置インクリメント(++it)は次の要素に進み、更新されたイテレータを返します。一方、後置インクリメント(it++)は進む前の値を返します。前置インクリメントの方が効率的な場合が多いため、一般的に推奨されます。
main.cpp
1234567891011121314151617181920212223242526272829303132#include <iostream> #include <deque> struct Point { int x, y; void print() const { std::cout << "(" << x << ", " << y << ")\n"; } }; int main() { std::deque<Point> points = {{1, 2}, {3, 4}, {5, 6}}; auto it = points.begin(); // Access element using * std::cout << "First element: "; (*it).print(); // Access member using -> std::cout << "First element via ->: "; it->print(); // Prefix increment ++it; std::cout << "After prefix ++it, element: "; it->print(); // Postfix increment it++; std::cout << "After postfix it++, element: "; it->print(); }
上記のコードでは、参照外しとメンバーアクセスの両方が使われています。(*it).print() と it->print() は、イテレータが指すオブジェクトの print メソッドを呼び出し、機能的には同じです。前置インクリメント(++it)は使用前にイテレータを進め、後置インクリメント(it++)は現在の値を返した後に進めます。単純な場合は同様に動作しますが、複雑なイテレータでは前置インクリメントの方が効率的です。要素自体へアクセスするには *it、メンバーへアクセスするには it->member を使用します。
main.cpp
12345678910111213141516171819#include <iostream> #include <vector> int main() { std::vector<int> numbers = {10, 20, 30}; auto it = numbers.end(); // Points one past the last element // Mistake: Dereferencing end() is undefined behavior // std::cout << *it << "\n"; // Uncommenting this line is dangerous! // Mistake: Incrementing past end() ++it; // Now it is beyond valid range // Even more dangerous to dereference now // std::cout << *it << "\n"; // Still undefined behavior std::cout << "Avoid dereferencing or incrementing past end().\n"; }
イテレータに関する一般的な誤りは、コンテナの終端を越えてインクリメントしたり、end() が返すイテレータをデリファレンスすることです。end() は最後の要素の直後を指しているため、*end() を使用したり、これをインクリメントすると未定義動作となります。イテレータをデリファレンスまたは進める前に、必ずそのイテレータが end() と等しくないことを確認してください。前述の例はこのルールに従っており、有効な範囲内でイテレーションを行い、*、->、インクリメント演算子を安全に使用しています。
一部のイテレータ型、特に単純なポインタでない場合、前置インクリメント(++it)は後置インクリメント(it++)よりも効率的です。後置インクリメントは一時的なコピーを生成する場合があるためです。パフォーマンスが重要なコードでは、以前の値が必要な場合を除き、前置インクリメントを推奨します。
フィードバックありがとうございます!
AIに質問する
AIに質問する
何でも質問するか、提案された質問の1つを試してチャットを始めてください