我做了一个瓷砖匹配游戏。它有一个Board对象,它包含一个卡对象向量并将事件委托给它们。董事会事件处理中包含以下代码:
// Counting logic-driving card states
int cardFaceUpCounter = 0;
std::vector<Card*> faceUpCards(2);
// Checking for logic-driving card states
for (auto& card : this->boardMatrix)
{
if (this->isCardInAnim(&card))
{
return;
}
if (this->isCardFaceUp(&card))
{
++cardFaceUpCounter;
faceUpCards[cardFaceUpCounter - 1] = &card;
}
}
我刚刚在Pluralsight上完成了Kate Gregory的Beautiful C ++学习。 她认为我们应该避免编写循环,并应尽可能使用STL算法标题。 我发现她的论点和方法非常引人注目,因此我试图重构我最新的宠物项目以反映她的教诲。
上面的示例是我无法看到如何使用STL算法更好地传达意图并保持性能 - 单循环而不是两个或三个循环,尽管隐藏在算法调用中。 / p>
第二个问题是如果使用STL算法无法实现单循环效率,为了便于阅读,您仍然更喜欢这种方法。
答案 0 :(得分:1)
这是我在想的一个例子。
int cardFaceUpCounter = 0;
std::vector<Card*> faceUpCards(2);
if (std::any_of(boardMatrix.begin(), boardMatrix.end(), [&](auto& card) {
if (isCardFaceUp(&card))
faceUpCards[cardFaceUpCounter++] = &card;
return isCardInAnim(&card);
})) return;
答案 1 :(得分:1)
使用range-v3,它将类似于:
std::vector<Card*> faceUpCards = this->boardMatrix
| ranges::view::take_while([this](const auto& card){ return !isCardInAnim(&card);})
| ranges::view::filter([this](const auto& card){ return isCardFaceUp(&card); })
| ranges::view::transform([](auto& e){ return &e; });
只有STL,我会做类似的事情:
auto it = std::find_if(boardMatrix.begin(), boardMatrix.end(),
[this](const auto& card){ return isCardInAnim(&card);});
std::vector<Card*> faceUpCards(std::distance(boardMatrix.begin(), it), nullptr);
std::transform(boardMatrix.begin(), it,
faceUpCards.begin(),
[](auto& card){ return &card;});
faceUpCards.erase(std::remove_if(faceUpCards.begin(), faceUpCards.end(),
[this](const auto& card){ return !isCardFaceUp(&card); }),
faceUpCards.end());