C ++ में <=> ऑपरेटर क्या है?


215

जब मैं C ++ ऑपरेटरों के बारे में जानने की कोशिश कर रहा था , मैंने cppreference.com , * पर एक अजीब तुलना ऑपरेटर पर ठोकर खाई , जो इस तरह दिखता था:

यहां छवि विवरण दर्ज करें

"ठीक है, अगर ये C ++ में आम ऑपरेटर हैं, तो मैं उन्हें बेहतर तरीके से सीखता हूं", मैंने सोचा। लेकिन इस रहस्य को मिटाने के मेरे सारे प्रयास असफल रहे। यहां तक, स्टैक ओवरफ्लो पर मुझे अपनी खोज में कोई भाग्य नहीं था।

क्या <=> और C ++ के बीच कोई संबंध है ?

और अगर वहाँ है, तो यह ऑपरेटर वास्तव में क्या करता है?

* इस बीच cppreference.com ने उस पेज को अपडेट किया और अब <=>ऑपरेटर के बारे में जानकारी है ।


82
@ झटके: ओह कृपया, हमारे पास सामान के बारे में बहुत सारे प्रश्न हैं जो मानक में वोट नहीं दिए गए थे। हमारे पास एक कारण के लिए C ++ 20 टैग है। इस तरह का सामान बहुत अधिक विषय पर है।
निकोल बोलस

1
@ cubuspl42 bar< foo::operator<=>एक उदाहरण है कि यह <--ऑपरेटर की तरह कैसे हो सकता है ।
यक्क - एडम नेवरामॉन्ट 20

8
@ झटके: सही है। जैसे C ++ 11 कंपाइलर के बारे में एक टैग है जो C ++ 11 को लागू करता है। और C ++ 14 कंपाइलर्स के बारे में एक टैग है जो C ++ 14 को लागू करते हैं। और C ++ 17 कंपाइलर्स के बारे में है जो C ++ 17 को लागू करते हैं। नहीं, C ++ 20 C ++ 20 के सामान के लिए टैग है। और चूंकि यह सवाल C ++ 20 के बारे में है, इसलिए यह वहाँ है। टैग विकी जो गलत था, टैग ही नहीं।
निकोल बोलस

जवाबों:


180

इसे तीन-तरफा तुलना ऑपरेटर कहा जाता है ।

P0515 पेपर प्रस्ताव के अनुसार :

एक नया तीन-तरफ़ा तुलना ऑपरेटर है <=>,। अभिव्यक्ति a <=> bएक ऐसी वस्तु लौटाती है जो तुलना करती <0है a < b, >0यदि तुलना करती है a > b, और तुलना करती ==0है aऔर यदि bबराबर / बराबर है।

अपने प्रकार के लिए सभी तुलनाओं को लिखने के लिए, यह लिखें operator<=>कि उचित श्रेणी का रिटर्न:

  • लौटें एक _ordering अगर आपके प्रकार स्वाभाविक रूप से समर्थन करता है <, और हम कुशलतापूर्वक उत्पन्न करेंगे <, >, <=, >=, ==, और !=; अन्यथा एक असमानता लौटाते हैं , और हम कुशलता से == और ! = उत्पन्न करेंगे ।

  • यदि आपके प्रकार का a == bतात्पर्य है तो मजबूत लौटें f(a) == f(b)(प्रतिस्थापन, जहां f केवल गैर-लाभकारी कास्ट इंटरफ़ेस का उपयोग करके तुलना-योग्य स्थिति को पढ़ता है), अन्यथा कमजोर होकर लौटें।

Cppreference का कहना है:

तीन-तरफा तुलना ऑपरेटर भावों का रूप है

lhs <=> rhs   (1)  

अभिव्यक्ति एक वस्तु देता है कि

  • तुलना करता है <0अगरlhs < rhs
  • तुलना करता है >0अगरlhs > rhs
  • और तुलना करता ==0है lhsऔर rhsबराबर / बराबर हैं।

93
उन लोगों के लिए जो उलझन में हैं (जैसे कि मैं) "तुलना <0", "तुलना >0" और "तुलना ==0" का मतलब क्या है, उनका मतलब है <=>कि तर्कों के आधार पर रिटर्न एक नकारात्मक, सकारात्मक या शून्य मान है। बहुत पसंद strncmpऔर memcmp
कॉर्नस्टॉक

1
@Dai भी दोनों हालांकि 'a' < 'a'और 'c' < 'a'दोनों झूठे हैं, 'a' < 'a'और 'a' < 'c'नहीं कर रहे हैं। निम्नलिखित में मजबूत आदेश का पालन करना सही है: a != ba < b || b < a
रिवाल्वर_सेलॉट

1
@Revolver_Ocelot आह, तो यह परिभाषित किया जा सकता है / के रूप में उत्पन्न operator==(T x, T y) { return !(x < y) && !(y < x); }और operator!=(T x, T y) { return (x < y) || (y < x); }- आह-हा! बेशक यह एक सच्चे की तुलना में कम कुशल है ==क्योंकि यह दो बार तुलना करता है, लेकिन फिर भी साफ-सुथरा है।
दाई

3
"मजबूत वापसी" और "कमजोर वापसी" का क्या मतलब है?
लुसीडब्रोट

2
@hkBattousai का अर्थ यह है कि वस्तु की वापसी तब होती है, जब उसकी तुलना < 0सत्य से होती है। यानी अगर है a < bतो (a <=> b) < 0हमेशा सच है।
rmobis

116

पर 2017/11/11 , आईएसओ सी ++ समिति अपनाया हर्ब Sutter के लिए के प्रस्ताव <=> "अंतरिक्ष यान" तीन तरह तुलना ऑपरेटर कि करने के लिए जोड़ा गया था नई सुविधाओं में से एक के रूप में सी ++ 20सुसंगत तुलना सटर, मौरर और ब्राउन नामक पत्र में नए डिजाइन की अवधारणाओं को प्रदर्शित किया गया है। प्रस्ताव के अवलोकन के लिए, यहां लेख का एक अंश दिया गया है:

व्यंजक <=> b एक ऐसी वस्तु लौटाता है जो <0 की तुलना करता है तो <b , तुलना करता है > 0 यदि a> b , और तुलना करता है == 0 यदि a और b समान / समतुल्य है।

सामान्य मामला: टाइप वाई के साथ अपने टाइप एक्स के लिए सभी तुलना लिखने के लिए , सदस्यवार शब्दार्थ के साथ, बस लिखें:

auto X::operator<=>(const Y&) =default;

उन्नत मामले: टाइप वाई के साथ अपने टाइप एक्स के लिए सभी तुलना लिखने के लिए , बस ऑपरेटर लिखें <=> जो वाई लेता है , यदि वांछित है, तो सदस्यवार शब्दार्थ प्राप्त करने के लिए = डिफ़ॉल्ट का उपयोग कर सकते हैं और उपयुक्त श्रेणी प्रकार लौटा सकते हैं:

  • एक लौटें _ordering अगर आपके प्रकार स्वाभाविक रूप से समर्थन करता है < , और हम कुशलतापूर्वक सममित उत्पन्न करेंगे < , > , <= , > = , == , और =! ; अन्यथा एक असमानता लौटाते हैं , और हम कुशलता से सममित == और ! = उत्पन्न करेंगे ।
  • वापसी strong_ अगर आपके प्रकार के लिए एक == ख का तात्पर्य च (क) == च (ख) (प्रतिस्थापन, जहां केवल तुलना-मुख्य राज्य है कि सार्वजनिक उपयोग करते हुए पहुँचा जा सकता है पढ़ता स्थिरांक सदस्य), अन्यथा लौट weak_

तुलना श्रेणियाँ

पांच तुलना श्रेणियों को std::प्रकारों के रूप में परिभाषित किया गया है , जिनमें से प्रत्येक में निम्नलिखित पूर्वनिर्धारित मूल्य हैं:

+--------------------------------------------------------------------+
|                  |          Numeric  values          | Non-numeric |
|     Category     +-----------------------------------+             |
|                  | -1   | 0          | +1            |   values    |
+------------------+------+------------+---------------+-------------+
| strong_ordering  | less | equal      | greater       |             |
| weak_ordering    | less | equivalent | greater       |             |
| partial_ordering | less | equivalent | greater       | unordered   |
| strong_equality  |      | equal      | nonequal      |             |
| weak_equality    |      | equivalent | nonequivalent |             |
+------------------+------+------------+---------------+-------------+

इन प्रकारों के बीच निहित रूपांतरण इस प्रकार हैं:

  • strong_orderingमूल्यों के साथ { less, equal, greater} परोक्ष में धर्मान्तरित:
    • weak_orderingमूल्यों के साथ { less, equivalent, greater}
    • partial_orderingमूल्यों के साथ { less, equivalent, greater}
    • strong_equalityमूल्यों के साथ { unequal, equal, unequal}
    • weak_equalityमूल्यों के साथ { nonequivalent, equivalent, nonequivalent}
  • weak_orderingमूल्यों के साथ { less, equivalent, greater} परोक्ष में धर्मान्तरित:
    • partial_orderingमूल्यों के साथ { less, equivalent, greater}
    • weak_equalityमूल्यों के साथ { nonequivalent, equivalent, nonequivalent}
  • partial_orderingमूल्यों के साथ { less, equivalent, greater, unordered} परोक्ष में धर्मान्तरित:
    • weak_equalityमूल्यों के साथ { nonequivalent, equivalent, nonequivalent, nonequivalent}
  • strong_equalityमानों के साथ { } equal, unequalस्पष्ट रूप से इसमें रूपांतरित होता है:
    • weak_equalityमूल्यों के साथ { equivalent, nonequivalent}

तीन तरह से तुलना

<=>टोकन शुरू की है। वर्ण अनुक्रम पुराने स्रोत कोड में, <=>tokenizes <= >। उदाहरण के लिए, X<&Y::operator<=>अपने अर्थ को बनाए रखने के लिए एक स्थान जोड़ने की आवश्यकता है।

अधिभार संचालक <=>एक तीन-तरफा तुलनात्मक कार्य है और पूर्ववर्ती से अधिक <और निम्नतर है <<। यह एक प्रकार का रिटर्न देता है जिसकी तुलना शाब्दिक के खिलाफ की जा सकती है 0लेकिन अन्य रिटर्न प्रकारों की अनुमति दी जाती है जैसे कि अभिव्यक्ति टेम्पलेट्स का समर्थन करना। <=>भाषा में और मानक पुस्तकालय में परिभाषित सभी ऑपरेटर 5 पूर्वोक्त std::तुलना श्रेणी प्रकारों में से एक को लौटाते हैं।

भाषा प्रकारों के लिए, निम्नलिखित अंतर्निहित <=>समान-प्रकार की तुलनाएं प्रदान की जाती हैं। सभी विवश हैं , सिवाय इसके कि जहां अन्यथा उल्लेख किया गया है। इन तुलनाओं को स्केलर प्रमोशन / रूपांतरणों का उपयोग करके पूरी तरह से लागू नहीं किया जा सकता है।

  • के लिए bool, अभिन्न, और सूचक प्रकार, <=>रिटर्न strong_ordering
  • सूचक प्रकारों के लिए, विभिन्न cv- योग्यता और व्युत्पन्न-आधार रूपांतरणों को एक सजातीय निर्मित में आह्वान करने की अनुमति है <=>, और अंतर्निहित विषम हैं operator<=>(T*, nullptr_t)। केवल एक ही वस्तु / आवंटन के लिए बिंदुओं की तुलना स्थिर अभिव्यक्ति है।
  • मूलभूत फ़्लोटिंग बिंदु प्रकारों के लिए, <=>रिटर्न partial_ordering, और बड़े फ़्लोटिंग पॉइंट प्रकार के तर्कों को व्यापक रूप से लागू किया जा सकता है।
  • गणना के लिए, <=>गणना के अंतर्निहित प्रकार के समान ही रिटर्न देता है <=>
  • के लिए nullptr_t, <=>रिटर्न strong_orderingऔर हमेशा पैदावार equal
  • Copyable सरणियों के लिए, T[N] <=> T[N]के रूप में एक ही प्रकार के रिटर्न Tकी <=>और प्रदर्शन lexicographical elementwise तुलना। <=>अन्य सरणियों के लिए नहीं है ।
  • के लिए voidवहाँ नहीं है <=>

इस ऑपरेटर के आंतरिक कामकाज को बेहतर ढंग से समझने के लिए, कृपया मूल पेपर पढ़ें । यह वही है जो मैंने खोज इंजन का उपयोग करके पाया है।


1
जैसे कि cpp पहले से ही जटिल नहीं था। बस एक तुलना विधि क्यों नहीं लिखी ...
Leandro

6
अंतरिक्ष यान ऑपरेटर @Leandro है कि तुलना विधि। इसके अतिरिक्त, यह जस्ट वर्क्स और छह अन्य तुलना ऑपरेटरों को (या हटाता है) लिखता है। मैं छह अलग-अलग बॉयलर पर लिखे गए एक तुलना ऑपरेटर फ़ंक्शन ले जाऊंगा।
बेनामी

ध्यान दें कि _equalityप्रकार मर गए: यह पता चला कि <=>चार संबंधपरक ऑपरेटरों के साथ अच्छा खेलता है, लेकिन दो समानता ऑपरेटरों के साथ नहीं है (हालांकि आम मामले का समर्थन करने के लिए कुछ गहन सिंथैटिक चीनी है जहां आप उन सभी को चाहते हैं)।
डेविस हेरिंग

12

संदर्भित वेब पेज के बदलने के बाद से यह उत्तर अप्रासंगिक हो गया है

वेब पेज आप संदर्भित कर रहे टूट गया था। उस दिन बहुत कुछ संपादित किया जा रहा था और अलग-अलग हिस्से सिंक में नहीं थे। जब मैं देख रहा था तो यह स्थिति थी:

पृष्ठ के शीर्ष पर यह वर्तमान में मौजूद तुलना ऑपरेटरों (C ++ 14 में) को सूचीबद्ध करता है। वहां कोई नहीं <=>है।

पृष्ठ के निचले भाग में, उन्हें समान ऑपरेटरों को सूचीबद्ध करना चाहिए था, लेकिन उन्होंने नासमझ बना दिया और इस भविष्य के सुझाव को जोड़ दिया।

gcc<=>अभी तक (और साथ -std=c++14, कभी नहीं) के बारे में पता नहीं है , इसलिए यह सोचता है कि आप का मतलब है a <= > b। यह त्रुटि संदेश समझाता है।

यदि आप पांच साल से एक ही चीज की कोशिश करते हैं, तो आपको शायद एक बेहतर त्रुटि संदेश मिलेगा, कुछ ऐसा <=> not part of C++14.


1
वेब पेज ओपी लिंक सही है, जैसा कि आपके द्वारा लिंक किया गया अलग पेज है। यह <=>ऑपरेटर को (C ++ 20 के बाद से) लेबल के साथ योग्य बनाता है, आपको बताता है कि मानक का कौन सा संस्करण इसमें उम्मीद करता है। मानक लेबलिंग एक सम्मेलन है जो cppreference.com का अनुसरण करता है। बेशक आपके पास एक संकलक नहीं है जो आपके लिए समर्थन करने के लिए एक टाइम मशीन में वापस आ गया है, लेकिन cpprefernce आपको (सही ढंग से) बताता है कि क्या उम्मीद है।
स्पेंसर

हां, लेकिन ... जवाब नहीं। आप टिप्पणी कर रहे हैं ... या कुछ और।
qlp

2
मैं सवाल के रूप में एक ही वेब पेज से लिंक करना चाहता था, लेकिन चूक गया। मुझे लगता है कि मैंने सवाल के उन हिस्सों का जवाब दिया जो अन्य उत्तर नहीं थे। मैंने मुख्य साहसिक प्रश्न को नजरअंदाज कर दिया क्योंकि अन्य ने पहले ही उत्तर दे दिया था।
स्टिग हेमर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.