C ++ Templates - Panduan Lengkap, Edisi ke-2 memperkenalkan 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;
}
Dan itu menjelaskan penggunaan “b < a ? a : b”
bukannya “a < b ? b : a”
:
Perhatikan bahwa maks () templat menurut [StepanovNotes] dengan sengaja mengembalikan “b <a? a: b "bukannya" a <b? b: a ”untuk memastikan bahwa fungsi berperilaku dengan benar meskipun kedua nilai tersebut setara tetapi tidak sama.
Bagaimana cara memahami " even if the two values are equivalent but not equal.
"? “a < b ? b : a”
sepertinya punya hasil yang sama buat saya.
a
danb
yang setara , maka!(a < b) && !(b < a)
benar, sehinggaa < b
danb < a
keduanya palsu, sehingga dalamb < a ? a : b
,b
dikembalikan, yang tidak apa yang Anda inginkan ... Anda ingina < b ? b : a
.a
danb
denganstd::addressof
et. Al.a = max(a, b);
(berulang kali), Anda mungkin tidak ingin mengganti yanga
tidak perlu.a
dengan salinana
).std::addressof
tidak relevan. Padahal, untuk yang diberikanT max(T a, T b)
kita sudah tahuaddressof(a) != addressof(b)
.Jawaban:
std::max(a, b)
memang ditentukan untuk kembalia
ketika keduanya setara.Itu dianggap kesalahan oleh Stepanov dan yang lainnya karena merusak properti berguna yang diberikan
a
danb
, Anda selalu dapat mengatasinya{min(a, b), max(a, b)}
; untuk itu, Anda inginmax(a, b)
kembalib
ketika argumennya setara.sumber
{min(a, b), max(b, a)}
?max(a,b)
mengembalikan return if-and-only-ifmin(a,b)
b, dan sebaliknya sehingga keduanya merupakan kebalikan dari yang lainnya dan set (unordered){min(a,b), max(a,b)}
selalu sama dengan{a,b}
.min
danmax
untuk apa pun kecuali cap waktu (tombol sortir) dalam skenario itu tidak masuk akal. Peristiwa (objek) itu sendiri seharusnya tidak dapat dibandingkan jika kesetaraan tidak menyiratkan pertukaran. Satu-satunya cara{min(a, b), max(a, b)}
membuat setiap akal sebagai mekanisme semacam ini jika benda yang dipertukarkan.Jawaban ini menjelaskan mengapa kode yang diberikan salah dari sudut pandang standar C ++, tetapi tidak sesuai konteks.
Lihat jawaban @ TC untuk penjelasan kontekstual.
Standar mendefinisikan
std::max(a, b)
sebagai berikut [alg.min.max] (penekanan adalah milikku):Setara sini berarti bahwa
!(a < b) && !(b < a)
adalahtrue
[alg.sorting # 7] .Secara khusus, jika
a
danb
setara, baika < b
danb < a
sedangfalse
, maka nilai di sebelah kanan:
akan dikembalikan di operator bersyarat, jadia
harus di sebelah kanan, jadi:... sepertinya jawaban yang benar. Ini adalah versi yang digunakan oleh libstdc ++ dan libc ++ .
Jadi informasi dalam kutipan Anda tampaknya salah menurut standar saat ini, tetapi konteks yang didefinisikan mungkin berbeda.
sumber
X
).a<b
danb<a
keduanya bisa salah karena mereka tidak terurut (satu atau keduanya NaN, jadi==
juga salah). Itu bisa dilihat sebagai semacam kesetaraan. terkait longgar:maxsd a, b
mengimplementasikan instruksi x86a = max(b,a) = b < a ? a : b
. ( Apa instruksi yang memberikan FP min tanpa cabang dan maks pada x86? ). Instruksi menjaga operan sumber (yang ke-2) pada unordered, sehingga loop di atas array akan memberi Anda NaN jika ada NaN. Tetapimax_seen = max(max_seen, a[i])
akan mengabaikan NaNs.Intinya adalah yang harus dikembalikan ketika mereka setara;
std::max
harus kembalia
(yaitu argumen pertama) untuk kasus ini.Jadi
a < b ? b : a
harus digunakan; di sisi lain,b < a ? a : b;
akan kembali denganb
tidak benar.(Seperti yang dikatakan @Holt, kutipannya sepertinya berlawanan.)
"kedua nilai tersebut setara tetapi tidak sama" berarti mereka memiliki nilai yang sama ketika dibandingkan, tetapi mereka akan menjadi objek yang berbeda di beberapa aspek lainnya.
misalnya
sumber
std::max(a, b)
harus kembalia
, jikaa
danb
setara?a
danb
setara, maka!(a < b) && !(b < a)
benar, jadia < b
danb < a
salah, jadi ...?