C++ Templates - The Complete Guide, 2nd Edition 引入了 max 模板:
template<typename T>
T max (T a, T b)
{
// if b < a then yield a else yield b
return b < a ? a : b;
}
它解释了使用 “b < a ? a : b”
而不是 “a < b ? b : a”
:
请注意,根据 [StepanovNotes] 的 max() 模板有意返回“b < a ? a : b" 而不是 "a < b ? b : a” 以确保即使两个值相等但不相等,函数也能正确运行。
如何理解“even if the two values are equivalent but not equal.
”? “a < b ? b : a”
似乎对我有相同的结果。
a
和 b
等价,则 !(a < b) && !(b < a)
为真,因此 a < b
和 b < a
都是false,因此在 b < a ? a : b
中,返回 b
,这不是您想要的……您想要 a < b ? b : a
。
a = max(a, b);
,您可能不想不必要地替换 a
。
a
的副本覆盖 a
)。
std::addressof
无关紧要。事实上,对于给定的 T max(T a, T b)
,我们已经知道 addressof(a) != addressof(b)
。
当两者相等时,确实指定 std::max(a, b)
返回 a
。
Stepanov 和其他人认为这是一个错误,因为它破坏了给定 a
和 b
的有用属性,您始终可以使用 {min(a, b), max(a, b)}
对它们进行排序;为此,您希望 max(a, b)
在参数相等时返回 b
。
这个答案解释了为什么从 C++ 标准的角度来看给定的代码是错误的,但它是脱离上下文的。
有关上下文解释,请参阅 @T.C.'s answer。
该标准将 std::max(a, b)
定义为如下 [alg.min.max](重点是我的):
模板
这里的等价意味着 !(a < b) && !(b < a)
是 true
[alg.sorting#7]。
特别是,如果 a
和 b
等价,则 a < b
和 b < a
都是 false
,所以在条件运算符中会返回 :
右边的值,所以 a
有在右边,所以:
a < b ? b : a
...似乎是正确的答案。这是 libstdc++ 和 libc++ 使用的版本。
因此,根据当前标准,您报价中的信息似乎是错误的,但定义它的上下文可能会有所不同。
X
的定义)。
a<b
和 b<a
都可能是假的,因为它们是无序的(一个或两个都是 NaN,所以 ==
也是假的)。这可以看作是一种对等。松散相关:x86 的 maxsd a, b
指令实现了 a = max(b,a) = b < a ? a : b
。 (What is the instruction that gives branchless FP min and max on x86?)。该指令使源操作数(第二个)保持无序,因此如果有任何 NaN,则数组上的循环将为您提供 NaN。但 max_seen = max(max_seen, a[i])
将忽略 NaN。
关键是当它们相等时应该返回哪个;对于这种情况,std::max
必须返回 a
(即第一个参数)。
如果它们等价,则返回 a。
所以应该使用a < b ? b : a
;另一方面,b < a ? a : b;
将错误地返回 b
。
(正如@Holt 所说,引用似乎相反。)
“两个值相等但不相等”是指它们在比较时具有相同的值,但在某些方面它们可能是不同的对象。
例如
struct X { int a; int b; };
bool operator< (X lhs, X rhs) { return lhs.a < rhs.a; }
X x1 {0, 1};
X x2 {0, 2};
auto x3 = std::max(x1, x2); // it's guaranteed that an X which cantains {0, 1} is returned
a
和 b
是等价的,您能否详细说明为什么 std::max(a, b)
必须返回 a
?
a
和 b
等价,则 !(a < b) && !(b < a)
为真,因此 a < b
和 b < a
为假,所以...?
不定期副业成功案例分享
{min(a, b), max(b, a)}
吗?max(a,b)
将返回 a if-and-only-ifmin(a,b)
返回 b 并且 反之亦然 是合乎逻辑的,因此它们彼此相反并且 (无序)集合{min(a,b), max(a,b)}
总是等于{a,b}
。min
和max
应用于除 timestamp (排序键)之外的任何内容都是没有意义的。如果平等并不意味着可互换性,那么事件(对象)本身甚至不应该具有可比性。{min(a, b), max(a, b)}
使 any 作为一种排序机制有意义的唯一方法是对象是否可互换。