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

时间:2017-10-12 11:29:17

标签: c++ std

cppreference上有一个关于如何使用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';

但是,在unique的要求部分中说明了

  

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

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

2 个答案:

答案 0 :(得分:2)

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

a ~ a

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

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

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

事实是,与自身进行比较对于该算法来说几乎没用,所以UB在这里做了大多数实现中作者所期望的。

有效的实现可能会检查谓词的反身性,如果错误做任何事情(如UB)。

答案 1 :(得分:0)

unique:&#34;消除范围内每个连续的等效元素组中的第一个元素&#34;

如果将样本谓词的元素定义为仅空格,那么一切都是正确的。等效性应仅适用于空间。 &#39; N&#39;不是空格,所以谓词返回false。