इक्विटी ऑपरेटर को C++ 20 में कस्टम स्पेसशिप ऑपरेटर कार्यान्वयन के लिए परिभाषित नहीं किया जाता है




c++20 spaceship-operator (2)

अन्य उत्तर वास्तव में अच्छी तरह से समझाते हैं कि भाषा इस तरह क्यों है। मैं बस यह जोड़ना चाहता था कि यदि यह स्पष्ट नहीं है, तो यह निश्चित रूप से उपयोगकर्ता द्वारा प्रदान किए गए operator<=> को डिफ़ॉल्ट operator== साथ संभव है। आपको बस डिफॉल्ट किए गए operator== को स्पष्ट रूप से लिखना होगा:

struct X
{
    int Dummy = 0;
    auto operator<=>(const X& other) const
    {
        return Dummy <=> other.Dummy;
    }
    bool operator==(const X& other) const = default;
};

मैं C ++ 20 में नए स्पेसशिप ऑपरेटर <=> साथ एक अजीब व्यवहार में चल रहा हूं। मैं Visual Studio 2019 संकलक का उपयोग /std:c++latest साथ कर रहा हूँ।

यह कोड ठीक संकलित करता है, जैसा कि अपेक्षित था:

#include <compare>

struct X
{
    int Dummy = 0;
    auto operator<=>(const X&) const = default; // Default implementation
};

int main()
{
    X a, b;

    a == b; // OK!

    return 0;
}

हालाँकि, अगर मैं X को इसमें बदलता हूँ:

struct X
{
    int Dummy = 0;
    auto operator<=>(const X& other) const
    {
        return Dummy <=> other.Dummy;
    }
};

मुझे निम्नलिखित संकलक त्रुटि मिलती है:

error C2676: binary '==': 'X' does not define this operator or a conversion to a type acceptable to the predefined operator

मैंने इसे क्लैंग पर भी आजमाया और मुझे भी ऐसा ही व्यवहार मिला।

मैं कुछ स्पष्टीकरण की सराहना करता हूं कि डिफ़ॉल्ट कार्यान्वयन operator== सही ढंग से क्यों उत्पन्न करता है, लेकिन कस्टम नहीं करता है।


इस सुविधा के मानकीकरण के दौरान, यह निर्णय लिया गया था कि समानता और आदेश को तार्किक रूप से अलग किया जाना चाहिए। जैसे, समानता परीक्षण ( == और != ) का उपयोग operator<=> को कभी नहीं मनाएगा operator<=> । हालाँकि, यह अभी भी एक घोषणा के साथ दोनों को डिफ़ॉल्ट रूप से सक्षम करने के लिए उपयोगी के रूप में देखा गया था। इसलिए यदि आप डिफॉल्ट operator<=> , तो यह तय किया गया कि आप भी डिफॉल्ट operator== (जब तक कि आप इसे बाद में परिभाषित नहीं करते हैं या पहले परिभाषित कर चुके हैं)।

जैसा कि यह निर्णय क्यों किया गया था , मूल तर्क इस तरह से होता है। std::string पर विचार करें। दो तारों का आदेश शाब्दिक है; प्रत्येक वर्ण के दूसरे स्ट्रिंग में प्रत्येक वर्ण के मुकाबले इसका पूर्णांक मान होता है। आदेश देने के परिणामस्वरूप पहली असमानता होती है।

हालांकि, स्ट्रिंग्स के समानता परीक्षण में शॉर्ट-सर्किट होता है। यदि दो तार बराबर लंबाई के नहीं हैं, तो चरित्र-वार तुलना करने का कोई मतलब नहीं है; वे समान नहीं हैं। तो अगर कोई समानता परीक्षण कर रहा है, तो आप इसे लंबे समय तक नहीं करना चाहते हैं यदि आप इसे शॉर्ट-सर्किट कर सकते हैं।

यह पता चला है कि उपयोगकर्ता-परिभाषित आदेश की आवश्यकता वाले कई प्रकार भी समानता परीक्षण के लिए कुछ शॉर्ट-सर्किट तंत्र की पेशकश करेंगे। लोगों को केवल operator<=> को लागू करने से रोकने के लिए operator<=> और संभावित प्रदर्शन को दूर फेंकने के लिए, हम प्रभावी रूप से सभी को दोनों करने के लिए मजबूर करते हैं।







spaceship-operator