受 C++20 修剪的可爱 cppreference示例的启发,我编写了以下代码(我已将返回类型更改为void
和 arg 为,std::string&
因为我的“问题”(我正在发明学习 C++20 的问题)不存在于使用std::string_view
arg 并返回的原始代码std::string
)。
void trim(std::string& in)
{
auto view
= std::views::all(in)
| std::views::drop_while(isspace)
| std::views::reverse
| std::views::drop_while(isspace)
| std::views::reverse;
std::string result{view.begin(), view.end()};
in = std::move(result);
}
这里的问题是这不是就地的,这意味着创建了新字符串。我可以编写更丑陋的代码来就地执行此操作,并且我知道传统的 C++ 算法不知道容器的存在,但我想知道 C++20 是否有一些技巧可以让我以优雅的方式进行修剪,但也是就地的。
这也是我丑陋的就地修剪(不确定它是否可以正常工作,但想法是它会就地修剪):
void trim2(std::string& s) {
// ugly and error prone, but inplace
const auto it1 = std::ranges::find_if_not(s, isspace);
const auto it2 = std::ranges::find_if_not(s.rbegin(), s.rend(), isspace);
const size_t shift = (it1==s.end()) ? 0: std::distance(s.begin(), it1);
const size_t result_size = s.size() - shift - ((it2==s.rend()) ? 0 : std::distance(s.rbegin(), it2));
std::shift_left(s.begin(), s.end(), shift);
s.resize(result_size);
}
编辑:最初这个问题声称in.assign
是 UB,但 TC 纠正了我。但根据我对 C++23 草案分配的理解,仍然会导致创建临时字符串。