c++ - std::unique 没有等价关系的例子(去掉连续的空格)

标签 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';

但是,在唯一性的要求部分中指出

Elements are compared using the given binary predicate p. The behavior is undefined if it is not an equivalence relation.

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

最佳答案

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

a ~ a

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

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

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

事实是,与自身比较对于该算法几乎没有用,因此此处的 UB 符合作者在大多数实现中所期望的。

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

关于c++ - std::unique 没有等价关系的例子(去掉连续的空格),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46708446/

相关文章:

C++派生类和虚析构函数

c++ - 单生产者、多消费者架构

c++ - 在保留原始顺序的同时删除/删除多个 std::vector 元素的最有效方法?

c++ - 标准库源文件

c++ - VirtualAlloc 的顺序似乎很重要 (c++)

c++ - 为什么这会重复打印换行符?

c++ - 在 MFC 中创建属性网格

c++ - std::bind 与 std::shared_ptr

c++ - 使用 std::thread 和良好实践并行化循环

c++ - 为什么需要 std::forward,默认情况下编译器不能做正确的事情