【发布时间】:2022-11-23 15:43:46
【问题描述】:
由于 std::remove 不会调整 std::string 的大小,我想出了一个解决方法:
std::string s{"aabcdef"};
std::remove_if(s.begin(), s.end(), [&s](char a)
{
if (a == 'a')
{
s.pop_back();
return true;
}
return false;
});
预期输出:bcd。实际输出:bcd。 由于某种原因,它擦除 4 个字符而不是预期的 2 个字符。如果我尝试传递一个 int 而不是计数真的在 lambda 中调用它按预期工作:
int removes{};
std::remove_if(s.begin(), s.end(), [&removes](char a)
{
if (a == 'a')
{
++removes;
return true;
}
return false;
});
for (int i{}; i < removes; ++i) s.pop_back(); //s = "bcdef"
【问题讨论】:
-
pop_back被调用前remove_if可以移动任何东西,而不是之后。听起来你只是想要擦除 - 删除习惯用法。您可以在 C++20 中使用 std::erase_if,或者在 C++17 或更早版本中编写您自己的等效项。 -
为什么不直接使用从
remove返回的迭代器并将其传递给erase?std::erase(std::remove(s.begin(), s.end(), 'a')), s.end()) -
@AlanBirtles 你想要一个成员
s.erase()。非成员擦除只是std::erase(s, 'a');。