简体   繁体   English

如何用 STL 算法或迭代器替换这个原始循环? (避免未经检查的下标运算符)

[英]How do I replace this raw loop with an STL algorithm or iterators? (avoiding unchecked subscript operator)

I'm implementing a generic clone of the Snake game in C++ as an exercise in following the C++ Recommended Guidelines.我正在 C++ 中实现Snake 游戏的通用克隆,作为遵循 C++ 推荐指南的练习。 I'm currently working on the Snake's update() method, which is tiggering a Guideline-violation for using the unchecked subscript operator in a for loop:我目前正在研究 Snake 的 update() 方法,该方法在 for 循环中使用未经检查的下标运算符会触发违反指南:

Prefer to use gsl::at() instead of unchecked subscript operator ( bounds.4 ).更喜欢使用 gsl::at() 而不是未经检查的下标运算符( bounds.4 )。

I want to avoid the redundant range change check of gsl::at() / container::at(), and don't want to suppress the warning either.我想避免 gsl::at() / container::at() 的冗余范围更改检查,也不想抑制警告。 With that in mind, how can I replace this raw loop with something more Guideline-friendly?考虑到这一点,我怎样才能用更符合指南的东西来替换这个原始循环? (eg. an STL algorithm, iterators, what have you) (例如,一个 STL 算法,迭代器,你有什么)

void Snake::update() noexcept {  
  if (hasTrailingSegments()) {
    for (auto i = body_segments.size() - 1; i > 0; i--) {
      body_segments[i] = body_segments[i - 1];
    }
  }  
  head() += heading;  
}

The code explained, bottom up:代码解释,自下而上:

  • the loop needs to ensure each body segment follows (= takes the position of) the one in front of it.循环需要确保每个主体部分都遵循(= 采用 position 的)它前面的那个。
  • body_segments is a std::vector of integer pairs. body_segments 是 integer 对的 std::vector。
  • hasTrailingSegments() ensure that "trailing_pieces" is size() > 1 (eg. player has more than just the head). hasTrailingSegments() 确保“trailing_pieces”是 size() > 1(例如,玩家不仅仅是头部)。
  • head() is simply body_segments[0] head() 只是 body_segments[0]

You can std::rotate the snake so that the old tail is the front element, and then overwrite that with the new segment.您可以std::rotate蛇,使旧尾巴是前面的元素,然后用新的片段覆盖它。

void Snake::update() noexcept {
  auto new_head = head() + heading;
  std::rotate(body_segments.begin(), body_segments.end() - 1, body_segments.end());
  head() = std::move(new_head);
}

Alternatively, you can copy_backward the body, overwriting the tail.或者,您可以copy_backward正文,覆盖尾部。

void Snake::update() noexcept {
  std::copy_backward(body_segments.begin(), body_segments.end() - 1, body_segments.end());
  head() += heading;
}

These are safe so long as a Snake always has at least one segment, which head() requires anyway.只要Snake始终至少有一个段,这些都是安全的, head()无论如何都需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM