2015-10-10 5 views
7

यह काम करता है:टेम्पलेट क्लास के नेस्टेड क्लास में किसी मित्र ऑपरेटर की परिभाषा कैसे प्रदान करें?

template<class Tim> 
struct Bob 
{ 
    struct Dave 
    { 
     Tim t{}; 
     friend bool operator < (const Dave& a, const Dave& b) 
     { 
      return a.t < b.t; 
     } 
    } d; 
}; 

यह काम नहीं करता:

1>ConsoleApplication1.obj : error LNK2019: unresolved external symbol "bool __cdecl operator<(struct Bob<int>::Dave const &,struct Bob<int>::Dave const &)" ([email protected][email protected][email protected]@@[email protected]) referenced in function "public: bool __thiscall std::less<struct Bob<int>::Dave>::operator()(struct Bob<int>::Dave const &,struct Bob<int>::Dave const &)const " ([email protected]@[email protected]@@@[email protected]@[email protected][email protected]@@[email protected]) 

:

template<class Tim> 
struct Bob 
{ 
    struct Dave 
    { 
     Tim t{}; 
     friend bool operator < (const Dave& a, const Dave& b); 
    } d; 
}; 

template<class Tim> 
bool operator < (const typename Bob<Tim>::Dave& a, const typename Bob<Tim>::Dave& b) 
{ 
    return a.t < b.t; 
} 

जब मैं उदाहरण के लिए एक नक्शे में इसका इस्तेमाल करने की कोशिश, मैं लिंकर त्रुटियों मिलता है।

int main() 
{ 
    std::map<Bob<int>::Dave, int> v; 
    v[{}]; 
} 

कैसे मैं सही ढंग से बाहर वर्ग इस ऑपरेटर परिभाषित कर सकते हैं?

+0

यदि आप चेतावनियां चालू करते हैं, तो आपको मिलता है: 'चेतावनी: मित्र घोषणा' बूल ऑपरेटर <(कॉन्स बॉब :: डेव और, कॉन्स बॉब :: डेव और) 'एक गैर-टेम्पलेट फ़ंक्शन घोषित करता है' (और एक संकेत इसके बारे में करें) - तो मित्र 'ऑपरेटर <' आप घोषित करते हैं, और 'टेम्पलेट <...> ऑपरेटर <' आप आगे परिभाषित करते हैं, वही बात नहीं है। – melak47

+0

@ melak47 वीएस2015 चेतावनी स्तर 4, मुझे कोई चेतावनी नहीं मिली है। –

+0

क्षमा करें, जीसीसी के आउटपुट देखें: http://coliru.stacked-crooked.com/a/bb58214d285f031f – melak47

उत्तर

4

आप सामान्य रूप से टेम्पलेट वर्ग और मित्र फ़ंक्शन को घोषित करके और कक्षा परिभाषा के भीतर विशेषज्ञता प्रदान करके ऐसी चीज करेंगे। हालांकि, इस मामले में यह इतना आसान नहीं है - एक निर्भर प्रकार होने पर Tim कक्षा गैर-कटौती संदर्भ में रखती है, इसलिए कटौती विफल हो जाएगी। हालांकि, इसके चारों ओर एक तरीका है:

#include <iostream> 
#include <type_traits> 
#include <map> 

template<class T> 
struct Bob; 

template<typename T, typename> 
bool operator < (const T& a, const T& b); 

struct DaveTag {}; 

template<class Tim> 
struct Bob 
{ 
    struct Dave : DaveTag 
    { 
     Tim t{}; 


     friend bool operator < <Bob<Tim>::Dave, void>(const typename Bob<Tim>::Dave& a, const typename Bob<Tim>::Dave& b); 
    } d; 
}; 

template<typename T, typename = typename std::enable_if<std::is_base_of<DaveTag, T>::value>::type> 
bool operator < (const T& a, const T& b) 
{ 
    return a.t < b.t; 
} 

struct X { 
    double t; 
}; 

int main() 
{ 
    std::map<Bob<int>::Dave, int> v; 
    v[{}]; 

    // This won't work 
    // X x, y; 
    //bool b = x < y; 

} 

असल में, क्या मैं यहाँ किया है संकलक अनुमान पूर्ण Bob<Tim>::Daveoperator< के लिए टेम्पलेट पैरामीटर के रूप में जाने है। हालांकि, स्पष्ट रूप से एक सरल परिभाषा T के लिए किसी भी प्रकार को कम करने की अनुमति देगी, संभावित रूप से कुछ मुश्किल-समझने वाली समस्याओं का कारण बनती है। इससे बचने के लिए मैंने एक छोटी टैग क्लास DaveTag जोड़ा जो Dave पर कुछ भी के लिए हमारे बहुत ही सामान्य operator< की तत्कालता को रोकने की अनुमति देता है।

+0

मैं यहां आपके प्रयास की सराहना करता हूं! –

+0

@NeilKirk कोई समस्या नहीं! मैं भी मजाक कर रहा था :) – Rostislav

+0

मैं एक कामकाज के साथ आया जो मेरी स्थिति के लिए काफी अच्छा है और थोड़ा आसान :) –

0

यहां एक संतोषजनक कामकाज है। मैं विभिन्न कारणों के लिए कक्षा में ऑपरेटर को लागू करने (परिभाषाओं उस बिंदु पर उपलब्ध नहीं, कुछ स्पष्ट टेम्पलेट इन्स्टेन्शियशन यहाँ पर जा रहा) नहीं करना चाहता था, लेकिन मैं निम्नलिखित के साथ रह सकते हैं:

struct Bob 
{ 
    struct Dave 
    { 
     Tim t{}; 

     static bool LessThan(const Dave& a, const Dave& b); 

     friend bool operator < (const Dave& a, const Dave& b) 
     { 
      return LessThan(a, b); 
     } 
    } d; 
}; 

अब स्थिर समारोह LessThan सामान्य तरीके से कक्षा से बाहर लागू किया जा सकता है।

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