لا يتم تعريف مشغل المساواة لتنفيذ مشغل سفينة الفضاء المخصص في C++ 20




c++20 spaceship-operator (2)

أثناء توحيد هذه الميزة ، تقرر الفصل بين المساواة والطلب. على هذا النحو ، لن تستدعي استخدامات اختبار المساواة ( == و != ) operator<=> أبدًا . ومع ذلك ، كان لا يزال من المفيد أن تكون قادرًا على تقصير كلاهما بإعلان واحد. لذلك ، إذا كنت تقوم operator<=> الافتراضي operator<=> ، فقد تقرر أيضًا أن تقصد أيضًا استخدام operator== الافتراضي operator== (ما لم تحدده لاحقًا أو حددته سابقًا).

لماذا اتخذ هذا القرار ، فإن المنطق الأساسي ينطبق على هذا النحو. النظر في std::string . ترتيب سلسلتين معجمية؛ كل حرف له قيمة عددية مقارنة مع كل حرف في السلسلة الأخرى. ينتج عن عدم المساواة الأول نتيجة الطلب.

ومع ذلك ، فإن اختبار المساواة في الأوتار له دائرة قصر. إذا كانت السلسلتان غير متساويتين في الطول ، فلا فائدة من إجراء مقارنة حرفية على الإطلاق ؛ انهم ليسوا متساوين. لذلك إذا كان شخص ما يقوم باختبار المساواة ، فأنت لا ترغب في القيام بذلك لفترة طويلة إذا أمكنك إجراء ماس كهربائى.

اتضح أن العديد من الأنواع التي تحتاج إلى ترتيب محدد من قِبل المستخدم ستوفر أيضًا بعض آليات دائرة قصر لاختبار المساواة. لمنع الناس من تنفيذ operator<=> فقط operator<=> والتخلص من الأداء المحتمل ، فإننا نجبر الجميع بفعالية على القيام بالأمرين معا.

أنا أواجه سلوكًا غريبًا مع مشغل سفينة الفضاء الجديد <=> في 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== . تحتاج فقط إلى كتابة operator== المتعثر بشكل صريح operator== :

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






spaceship-operator