std::没有等价关系的唯一示例(删除连续空格)

std::unique example with no equivalence relationship (remove consecutive spaces)

本文关键字:删除 连续 空格 唯一 等价关系 std      更新时间:2023-10-16

cpp首选项上有一个关于如何使用std::unique从字符串中删除连续空格的示例:

std::string s = "wanna go    to      space?";
auto end = std::unique(s.begin(), s.end(), [](char l, char r){
    return std::isspace(l) && std::isspace(r) && l == r;
});
// s now holds "wanna go to space?xxxxxxxx", where 'x' is indeterminate
std::cout << std::string(s.begin(), end) << 'n';

但是,在要求部分中,它指出了唯一的状态

使用给定的二进制谓词 p 比较元素。行为 如果不是等价关系,则未定义。

所以我的问题是:给定的例子有效吗?谓语显然不是反身的(两个"n"字符比较不相等),因此不是等价关系。

词确实不尊重Equivalence_relation,特别是反身性:

a ~ a

不过,您指出的示例可能是有效的,第一个'n'可能与第二个'n'不同。问题在于自我比较是错误的(空格字符除外)。

修复谓词的一种方法是考虑地址:

[](const char& l, const char& r)
{
    return (&l == &r)
        || (l == r && std::is_space(l));
}

事实是,与自身进行比较对于该算法来说大多是无用的,因此这里的 UB 在大多数实现中都达到了作者的期望。

有效的实现可能会检查谓词的反身性,如果错误,则执行任何操作(如 UB)。

unique:"从范围中每个连续的等效元素组中消除除第一个元素之外的所有元素"

如果将示例谓词的元素定义为仅空格,则一切正确。等价应仅应用于空格。'n' 不是空格,因此谓词返回 false。