Why use “b < a ? a : b” instead of “a < b ? b : a” to implement max template?

C++ Templates - The Complete Guide, 2nd Edition introduces the max template:

template<typename T>
T max (T a, T b)
{
// if b < a then yield a else yield b
return  b < a ? a : b;
}

And it explains using “b < a ? a : b” instead of “a < b ? b : a”:

Note that the max() template according to [StepanovNotes] intentionally returns “b < a ? a : b” instead of “a < b ? b : a” to ensure that the function behaves correctly even if the two values are equivalent but not equal.

How to understand "even if the two values are equivalent but not equal."? “a < b ? b : a” seems have the same result for me.

13353 次浏览

关键是当它们等价时应该返回哪个参数; 对于这种情况,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

这个答案解释了为什么给定的代码从 C + + 标准的角度来看是错误的,但是它脱离了上下文。

有关上下文的解释,请参见 @ T. C 的回答


该标准将 std::max(a, b)定义为以下 [ alg.min.max ](重点是我的) :

template<class T> constexpr const T& max(const T& a, const T& b);

要求 : 类型 T 是 LessThancompable (表18)。

返回 : 较大的值。

备注 : < strong > 当参数相等时返回第一个参数。

这里的等价物意味着 !(a < b) && !(b < a)true [藻类分类 # 7]

特别是,如果 ab是等价的,那么 a < bb < a都是 false,所以 :右边的值将在条件运算符中返回,所以 a必须在右边,所以:

a < b ? b : a

... 似乎是正确的答案。这是 Libstdc + + Libc + + 使用的版本。

因此,根据当前的标准,您报价中的信息似乎是错误的,但是定义它的上下文可能是不同的。

当两者等效时,std::max(a, b)确实被指定返回 a

Stepanov和其他人认为这是一个错误,因为它破坏了给定 ab的有用属性,您总是可以使用 {min(a, b), max(a, b)}对它们进行排序; 因此,当参数相等时,您希望 max(a, b)返回 b