cpprefjp / site

cpprefjpサイトのMarkdownソース
https://cpprefjp.github.io/
368 stars 152 forks source link

forward_list::erase_afterのサンプルコード修正 #1219

Closed range3 closed 6 months ago

range3 commented 6 months ago

forward_list::erase_afterの、"イテレート中に要素を削除する"サンプルコードについて、 条件一致した要素をerase_afterで削除した後、erase_afterの返り値をitに代入していますが、 この返り値は削除された要素の次の要素である"4"を指しているので、これをitに代入してしまうと、次のループで4のチェックが飛んでしまいます。(next == ls.end()) ここでは、erase_afterの返り値は単に無視すれば正しい動作になるかと思います。

テスト

わかり易さのために、std::forward_list<int> ls = {3, 1, 1, 4};に変更しています

修正前

int main() { std::forward_list ls = {3, 1, 1, 4};

// イテレート中に要素削除をするような場合には、 // 範囲for文は使用できない for (auto it = ls.before_begin();;) { auto next = std::next(it); if (next == ls.end()) break;

// 条件一致した要素を削除する
if (*next == 1) {
  // 削除された要素の次を指すイテレータが返される。
  it = ls.erase_after(it);
}
// 要素削除をしない場合に、イテレータを進める
else {
  ++it;
}

}

for (const auto& x : ls) { std::cout << x << std::endl; } }

3 1 4


## 修正後
- https://wandbox.org/permlink/QtI04xQkCT7ybIsU
```cpp
#include <iostream>
#include <forward_list>

int main()
{
  std::forward_list<int> ls = {3, 1, 1, 4};

  // イテレート中に要素削除をするような場合には、
  // 範囲for文は使用できない
  for (auto it = ls.before_begin();;) {
    auto next = std::next(it);
    if (next == ls.end())
      break;

    // 条件一致した要素を削除する
    if (*next == 1) {
      ls.erase_after(it);
    }
    // 要素削除をしない場合に、イテレータを進める
    else {
      ++it;
    }
  }

  for (const auto& x : ls) {
    std::cout << x << std::endl;
  }
}
3
4
faithandbrave commented 6 months ago

ありがとうございます。マージしました。 @range3 さんを編集チームに招待させていただきますね。後ほどGitHubから招待の通知が届くと思います。 編集チームに参加すれば、masterブランチに直接コミットできるようになります。 もしよろしければ、今後ともよろしくお願いします。

range3 commented 6 months ago

ありがとうございます。いつもcpprefjpをはじめc++コミュニティサイトにはお世話になっております。 今後もし貢献できることがあれば編集させていただきます。