“B <a का उपयोग क्यों करें? a: b ”के बजाय“ a <b? बी: "अधिकतम टेम्पलेट को लागू करने के लिए?


154

C ++ टेम्प्लेट्स - पूरा गाइड, दूसरा संस्करण अधिकतम टेम्पलेट पेश करता है :

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] के अनुसार अधिकतम () टेम्प्लेट जानबूझकर "b <a" देता है? a: b ”के बजाय“ a <b? बी: “यह सुनिश्चित करने के लिए कि फ़ंक्शन दो मानों के बराबर होने पर भी सही ढंग से व्यवहार करता है लेकिन समान नहीं है।

" even if the two values are equivalent but not equal." कैसे समझें ? “a < b ? b : a”लगता है मेरे लिए एक ही परिणाम है।


8
दिखता है मेरे लिए गलत ... दोनों जवाब 'सही' कर रहे हैं, लेकिन अगर aऔर bकर रहे हैं बराबर है, तो !(a < b) && !(b < a)सही है, तो a < bऔर b < aदोनों झूठे हैं, इसलिए में b < a ? a : b, bजो नहीं है कि आप क्या चाहते ... आप चाहते दिया जाता है, a < b ? b : a
होल्ट

1
आप अक्सर बराबर बीच भेद कर सकते aहैं और bसाथ std::addressofएट। अल।
कैलथ

14
यदि आप a = max(a, b);(बार-बार) करते हैं तो आप aअनावश्यक रूप से बदलना नहीं चाहेंगे ।
बो पर्सन

2
BTW इस टेम्प्लेट को कॉन्स्टिट-रेफरेंस द्वारा पैरामीटर लेना चाहिए और कॉन्स्ट-रेफरेंस द्वारा उन्हें वापस करना चाहिए, अन्यथा, आप बेकार प्रतियों का एक गुच्छा बना रहे हैं (और आप aएक कॉपी के साथ ओवरराइड करने जा रहे हैं a)।
होल्ट

3
@ कैलेथ: विहित प्रकार जिसमें समानता और समानता दोनों है CaseInsensitiveString। उस प्रकार के लिए, न तो <A और न ही A <a। लेकिन std::addressofअप्रासंगिक है। वास्तव में, दिए गए के लिए T max(T a, T b)हम पहले से ही जानते हैं addressof(a) != addressof(b)
MSalters

जवाबों:


150

std::max(a, b)वास्तव में निर्दिष्ट किया जाता है aजब दोनों बराबर होते हैं।

इसे Stepanov और अन्य लोगों द्वारा एक गलती माना जाता है क्योंकि यह दी गई उपयोगी संपत्ति को तोड़ता है aऔर b, आप हमेशा उनके साथ सॉर्ट कर सकते हैं {min(a, b), max(a, b)}; उसके लिए, आप तर्क के समतुल्य होने max(a, b)पर वापस लौटना चाहेंगे b


48
उस लिंक से "मेरे लिए ऐसा करना मुश्किल है जो लोग ऐसा करते हैं: आखिरकार, वे मेरे द्वारा लिखे गए अधिकतम सी + + मानक विनिर्देश का पालन करते हैं । मुझे यह देखने में कई साल लग गए कि मुझसे गलती हुई थी।" - वाह!
जैक ऐडली

23
क्या तुम अभी नहीं कर सकते {min(a, b), max(b, a)}?
कप्तान मैन

12
@ कैपटमैन: हां, लेकिन यह अभी भी कम स्पष्ट है। मैं यह तर्क दूंगा कि यह तार्किक समझ में आता है जो कि max(a,b)अगर-और-केवल-अगर min(a,b)रिटर्न बी, और इसके विपरीत लौटाएगा ताकि वे एक दूसरे के विपरीत हों और (अनियंत्रित) सेट {min(a,b), max(a,b)}हमेशा बराबर हो {a,b}
जैक आइडली

5
@ jpmc26: यदि कोई उदाहरण के लिए समय की घटनाओं की एक सूची छाँट रहा है, तो किसी को इस बात की परवाह नहीं करनी चाहिए कि क्या छंटनी का संचालन स्थिर है प्रत्येक इनपुट में एक बार दिखाई देने वाली घटना के बारे में, उसी तरह आउटपुट में एक बार दिखाई देता है। कुछ परिचालनों (जैसे डुप्लिकेट की गई घटनाओं को खोजने और समाप्त करने के लिए) को पूर्ण आदेश का उपयोग करने की आवश्यकता हो सकती है, लेकिन कई अन्य मामलों में, यह एक साथ ईवेंट को मनमाने क्रम में सूचीबद्ध करने के लिए स्वीकार्य हो सकता है, लेकिन उन्हें डुप्लिकेट करने या छोड़ने के लिए नहीं।
सुपरकैट

2
@supercat लागू करना minऔर maxकुछ भी लेकिन उस परिदृश्य में टाइमस्टैम्प (सॉर्ट कुंजी) का कोई मतलब नहीं है। अगर समानता समानता से नहीं होती है तो घटनाओं (वस्तुओं) को खुद भी तुलनीय नहीं होना चाहिए। एकमात्र तरीका किसी भी तरह {min(a, b), max(a, b)}से समझ में आता है कि क्या वस्तुएं विनिमेय हैं।
jpmc26

62

यह उत्तर बताता है कि दिए गए कोड C ++ मानक बिंदु-से-दृश्य में गलत क्यों है, लेकिन यह संदर्भ से बाहर है।

प्रासंगिक विवरण के लिए @ TC का उत्तर देखें ।


मानक std::max(a, b)निम्नानुसार परिभाषित करता है [alg.min.max] (जोर मेरा है):

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

आवश्यकता है : टाइप टी लेसनटैंकपरेबल (तालिका 18) है।

रिटर्न : बड़ा मूल्य।

टिप्पणी : तर्क के समतुल्य होने पर पहला तर्क लौटाता है।

यहाँ बराबर का मतलब है कि !(a < b) && !(b < a)है true [alg.sorting # 7]

विशेष रूप से, अगर aऔर bबराबर हैं, दोनों a < bऔर b < aकर रहे हैं false, तो के दाईं तरफ मूल्य :सशर्त ऑपरेटर में लौटा दी जाएगी, इसलिए aहै, तो सही पर हो गया है:

a < b ? b : a

... सही उत्तर लगता है। यह libstdc ++ और libc ++ द्वारा उपयोग किया जाने वाला संस्करण है ।

इसलिए आपकी बोली में जानकारी वर्तमान मानक के अनुसार गलत लगती है, लेकिन जिस संदर्भ में इसे परिभाषित किया गया है वह भिन्न हो सकता है।


4
गॉडबोल्ट लिंक जो इस मुद्दे की व्याख्या करता है (धन्यवाद की परिभाषा के लिए @songyuanyao X)।
होल्ट

1
@JackAidley मैंने यह निर्दिष्ट करने के लिए उत्तर दिया है कि तर्क वर्तमान मानक को लक्षित करता है।
होल्ट

@codekaizer मैं वास्तव में "अगर हम समान (ए, बी) को परिभाषित करते हैं, तो! कम्प (ए, बी) और&-COMP (बी, ए)" । मैंने लिंक को एक बेहतर उद्धरण (मानक में 3 लाइनें नीचे ...) में बदल दिया है।
होल्ट

1
आश्चर्य कोई भी नहीं चल बिन्दु, जहां उल्लेख किया है a<bऔर b<aदोनों झूठे हो सकता है क्योंकि वे अव्यवस्थित (एक या दोनों NaN, तो ==झूठा भी है)। इसे एक प्रकार की समानता के रूप में देखा जा सकता है। शिथिल संबंधित: x86 का maxsd a, bनिर्देश लागू होता है a = max(b,a) = b < a ? a : b। ( क्या निर्देश है जो x86 पर शाखा रहित FP मिनट और अधिकतम देता है? )। निर्देश स्रोत ऑपरेंड (दूसरा एक) को अनियंत्रित रखता है, इसलिए एक सरणी पर एक लूप आपको NaN देगा यदि कोई NaN थे। लेकिन max_seen = max(max_seen, a[i])NaNs की अनदेखी करेगा।
पीटर कॉर्डेस


21

वह बिंदु जो किसी के समकक्ष होने पर वापस किया जाना चाहिए; std::maxवापसी के लिए है aइस मामले के लिए (यानी पहला तर्क)।

यदि वे समकक्ष हैं, तो रिटर्न a

तो a < b ? b : aइस्तेमाल किया जाना चाहिए; दूसरी ओर, गलत तरीके b < a ? a : b;से लौटेगा b

(जैसा @ हॉल्ट ने कहा, उद्धरण इसके विपरीत लगता है।)

"दो मूल्य समान हैं, लेकिन समान नहीं हैं" का अर्थ है कि तुलना किए जाने पर उनका समान मूल्य है, लेकिन वे कुछ अन्य पहलुओं पर अलग-अलग वस्तुएं हैं।

जैसे

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

1
क्या आप विस्तार से बता सकते हैं कि क्यों std::max(a, b)लौटना है a, अगर aऔर bसमतुल्य हैं?
'ネ ロ

4
@ @ Choice ク - यह मानक के हिस्से पर सिर्फ एक मनमाना विकल्प है । हालांकि यह थोड़ा बुरा है अगर यह एक अच्छा है।
स्टोरीटेलर - अनसलैंडर मोनिका

क्या यह सिर्फ मेरे लिए है या इस सवाल के साथ विरोधाभास है? यदि aऔर bसमतुल्य हैं, तो !(a < b) && !(b < a)सच है, इसलिए a < bऔर b < aझूठे हैं, इसलिए ...?
होल्ट

2
@ @ Wants ク मुझे लगता है कि मानक केवल यह निर्धारित करना चाहता है; जब वे समतुल्य हों तो किसे लौटाया जाना चाहिए।
गीतयुयनाओ

1
मेरी स्मृति को ताज़ा करने के लिए धन्यवाद कि कोई वस्तु "समतुल्य" क्यों होगी, लेकिन "समान" नहीं।
जेफ वाकर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.