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:“确保即使两个值相等但不相等,函数也能正常运行。
如何理解“even if the two values are equivalent but not equal.
”? “a < b ? b : a”
似乎对我有同样的结果。
确实指定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](重点是我的):
template<class T> constexpr const T& max(const T& a, const T& b);
要求:类型T是LessThanComparable(表18)。
返回:值越大。
备注:当参数等效时返回第一个参数。
这里的等价意味着!(a < b) && !(b < a)
是true
[alg.sorting#7]。
特别是,如果a
和b
是等价的,a < b
和b < a
都是false
,所以:
右边的值将在条件运算符中返回,所以a
必须在右边,所以:
a < b ? b : a
......似乎是正确的答案。这是libstdc++和libc++使用的版本。
因此,根据当前标准,引用中的信息似乎是错误的,但定义它的上下文可能不同。
关键是当它们是等价的时候应该归还哪一个; std::max
必须返回a
(即第一个参数)。
如果它们是等价的,则返回
a
。
所以应该使用a < b ? b : a
;另一方面,b < a ? a : b;
将错误地返回b
。
(正如@Holt说的那样,引用似乎相反。)
“这两个值相等但不相等”意味着它们在比较时具有相同的值,但它们在某些其他方面是不同的对象。
EG
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