2015-05-26 6 views
6

यह सभी का अधिभार होता है कि मैं सभी ओवरलोडेड तुलना ऑपरेटर को कक्षा में लिखूं, इसलिए मैंने एक टेम्पलेट क्लास लिखा है जो < लागू करता है, < =,> =,! = यदि व्युत्पन्न कक्षा उपकरण == और <। यह काम कर रहा है लेकिन इसमें बहुत सी कलाकार हैं और यह स्पष्ट नहीं है कि "उत्सुकता से आवर्ती टेम्पलेट पैटर्न", तो मुझे आश्चर्य है कि क्या सरल समाधान हैं? संकलक (ऑपरेटर खत्म हो जाएगा ADL कर जो अंदर दिखेगा MyType और Comparable<MyType> के लिए MyType a, b; a > b; देखने का सामना करना पड़ता है जब के रूप मेंटेम्पलेट क्लास कार्यान्वयन तुलना ऑपरेटर

template <typename T> 
struct Comparable { 
    friend bool operator!=(T const & lhs, T const & rhs) { return !(lhs == rhs); } 
    friend bool operator> (T const & lhs, T const & rhs) { return rhs < lhs; } 
// ... 
}; 
class MyType : Comparable<MyType> { 
    int data; 
    friend bool operator==(MyType const & lhs, MyType const & rhs) { 
     return lhs.data == rhs.data; 
    } 
    friend bool operator< (MyType const & lhs, MyType const & rhs) { 
     return lhs.data < rhs.data; 
    } 
    public: 
// ... 
}; 

:

template <class Derived> 
class Comparable 
{ 
public: 

    bool operator!=(const Comparable<Derived>& other) { 
     return !(static_cast<Derived*>(this)->operator== 
        (*static_cast<const Derived*>(&other))); 
    } 

    bool operator<=(const Comparable<Derived>& other) { 
     return (static_cast<Derived*>(this)->operator== 
        (*static_cast<const Derived*>(&other))) 
       || (static_cast<Derived*>(this)->operator< 
        (*static_cast<const Derived*>(&other))); 
    } 

    bool operator>(const Comparable<Derived>& other) { 
     return !(static_cast<Derived*>(this)->operator== 
        (*static_cast<const Derived*>(&other))) 
       && !(static_cast<Derived*>(this)->operator< 
        (*static_cast<const Derived*>(&other))); 
    } 

    bool operator>=(const Comparable<Derived>& other) { 
     return !(static_cast<Derived*>(this)->operator< 
        (*static_cast<const Derived*>(&other))); 
    } 
}; 
+3

http://www.boost.org/doc/libs/1_58_0/libs/utility/operators.htm – interjay

+0

वहां हैं। मैंने उपरोक्त लिंक @interjay के समान समाधान का प्रस्ताव दिया होगा: कक्षा के अंदर मित्र फ़ंक्शन परिभाषाएं * इनलाइन * डी मुक्त फ़ंक्शंस हैं जिन्हें व्युत्पन्न प्रकार पर एडीएल के माध्यम से पाया जा सकता है। आप इसे ऑपरेटरों को प्रदान करने के लिए इसका उपयोग कर सकते हैं। –

उत्तर

4

मामले में यह टिप्पणी में वर्णन से स्पष्ट नहीं है यह आधार है), जहां आपको आवश्यक कार्यान्वयन मिलेगा: bool operator>(MyType const&, MyType const&)

ऑपरेटर मुक्त फ़ंक्शंस होने की अनुमति देता है जो उस प्रकार के बाहर है जो तुलना की जा रही है (इस मामले में आधार), जबकि ऑपरेटरों को केवल एडीएल के माध्यम से उपलब्ध कराया जाता है (दो तर्कों में से एक Comparable<MyType> होना चाहिए)। एक मुक्त फ़ंक्शन का उपयोग प्रकार-समरूपता भी प्रदान करता है, संकलक दोनों पक्षों पर अंतर्निहित रूपांतरण की अनुमति देगा, जहां सदस्य कार्य के मामले में यह केवल ऑपरेटर के दाईं ओर रूपांतरणों की अनुमति देगा।

namespace operators { 
    template <typename T> 
    bool operator>(T const & lhs, T const & rhs) { 
     return rhs < lhs;  
    } 
// rest of the operators come here 
    struct tag {}; 
} 
class MyType : operators::tag { 
    int data; 
    friend bool operator<(T const & lhs, T const & rhs) { 
     return lhs.data < rhs.data; 
    } 
//... 
}; 
:


पूर्णता के लिए, एक अलग चाल है कि किया जा सकता है एक टैग है कि ADL प्रयोजनों के लिए में है कि नाम स्थान लाने के लिए इस्तेमाल किया जा सकता के साथ मिलकर एक नाम स्थान में टेम्पलेट्स के रूप में ऑपरेटरों प्रदान करना है

चाल मूल रूप से वही है, सिवाय इसके कि ऑपरेटरों को आधार के अंदर नहीं मिला है, लेकिन एक नामस्थान में जो इसके साथ जुड़ा हुआ है। यह समाधान पिछले एक की तुलना में थोड़ा कम अच्छा है, क्योंकि यह विभिन्न प्रकार के दुरुपयोग के लिए खुला है, जिसमें using namespace operators; शामिल है जो टेम्पलेट ऑपरेटर सभी प्रकारों के लिए उपलब्ध कराएंगे।

+0

मैंने सोचा कि यह दोस्ती की noninheritability के कारण काम नहीं करेगा। – simon

+0

@ सिमॉन: इसका दोस्ती से कोई लेना देना नहीं है, 'मित्र' कीवर्ड का उपयोग वर्ग परिभाषा के अंदर एक मुक्त फ़ंक्शन की परिभाषा को अनुमति देने के लिए किया जाता है, लेकिन कार्यान्वयन केवल सार्वजनिक इंटरफ़ेस का उपयोग करते हैं। –

+0

हाँ, मैं देखता हूं, धन्यवाद। – simon

संबंधित मुद्दे