批准的答案不正确。
这个函数:
int foo(int a, int b) {
return a + b;
}
确实是保持平等和稳定的。
但是这个函数也是如此:
int bar(int a, int &b) {
auto ret = a + b;
++b;
return ret;
}
两者的实际区别在于 foo 是正则的(参见概念 regular_invocable),而 bar 不是。
一个保持相等但不稳定的函数的例子是:
int b = 0; // assume accessible by other threads
int zip(int a) {
auto ret = a + b;
++b;
return ret;
}
它是保持等式的,因为等式保持纯粹是静态,并且在任何给定时间,zip 确实会在相同的输入下给出相同的结果。
然而,zip 并不稳定,因为稳定性是动态的,并且在不同的时间,zip可能在相同的输入下给出不同的结果。
(如果全局变量b在调用之间没有改变,那么它会给出不同的结果。但是如果另一个线程减少b,并且没有发生其他变化,它会给出相同的结果。)
(如果没有其他线程可以访问 b 变量,尽管这实际上是如何实现的,我们将具有稳定性,因为我们可以观察到“显式干预修改”。这就是标准提到稳定性禁止“自发”的原因变化,也就是波动性,来自其他执行线程的变化等等。参见concepts.lib.general.equality)
还请注意,相等性保留不依赖于相等运算符的可用性(并且equal_comparable 概念实际上需要相等性保留)。平等没有明确定义,但应该被认为是可替代性或不可区分性,这在标准中经常提到,例如在strong_ordering中。
如果不保持相等,函数就不可能是稳定的,因为稳定性是静态的相等保持概念的动态扩展。