2011-04-07 17 views
35

के बिना सदस्य फ़ंक्शन का रिटर्न प्रकार प्राप्त करें मेरे पास कई कक्षाएं हैं जिन्हें मैं संशोधित नहीं कर सकता। प्रत्येक में एक कॉपी कन्स्ट्रक्टर होता है, कम से कम एक अन्य कन्स्ट्रक्टर, और एक फ़ंक्शन foo() जो कुछ मान देता है। मैं एक वर्ग टेम्पलेट बनाना चाहता हूं जो इन वर्गों में से प्रत्येक से प्राप्त हो सकता है, और इसमें डेटा सदस्य है जो foo() के वापसी प्रकार के समान प्रकार है (क्षमा करें यदि मुझे कुछ शब्दावली गलत है)।ऑब्जेक्ट

दूसरे शब्दों में, मैं एक वर्ग टेम्पलेट

template<typename T> class C : public T 
{ 
    footype fooresult; 
}; 

जहां footypeT::foo() की वापसी प्रकार है चाहते हैं।

अगर आधार वर्ग सब था, कहते हैं, एक डिफ़ॉल्ट निर्माता, मैं कर सकता

decltype(T().foo()) fooresult; 

(जीसीसी में C++ 0x कार्यक्षमता के साथ), लेकिन कक्षाएं आम में किसी विशेष निर्माता की जरूरत नहीं है , कॉपी कन्स्ट्रक्टर के अलावा।

जीसीसी decltype(this->foo()) की अनुमति नहीं देता है, हालांकि स्पष्ट रूप से यह संभावना है कि इसे सी ++ 0x मानक में जोड़ा जाएगा - क्या किसी को पता है कि यह कितना संभव है?

मुझे लगता है कि decltype(foo()) या decltype(T::foo()) के साथ कुछ करना संभव होना चाहिए लेकिन वे काम नहीं कर रहे हैं: जीसीसी फॉर्म cannot call member function 'int A::foo()' without object के रूप में त्रुटि देता है।

बेशक, मेरे पास एक अतिरिक्त टेम्पलेट पैरामीटर footype, या T प्रकार का गैर-वर्ग पैरामीटर भी हो सकता है, लेकिन क्या इससे बचने का कोई तरीका है?

+0

कोई शायद कुछ और सुरुचिपूर्ण के साथ आ जाएगा, लेकिन 'टाइपनाम डेमटाइप (mem_fun (& T :: foo())) :: result_type' या कुछ ऐसे के बारे में क्या? –

+0

@ स्टेव: जहां यह नाम 'return_type' आया था? – Nawaz

+0

@ नवाज: मेरी कल्पना। रीफ्रेश हिट करें ;-) –

उत्तर

55

आपको इसकी आवश्यकता नहीं है- याद रखें कि क्योंकि decltype इसके तर्क का मूल्यांकन नहीं करता है, तो आप केवल nullptr पर कॉल कर सकते हैं।

decltype(((T*)nullptr)->foo()) footype; 
29

एक अन्य विकल्प है:

#include <utility> 

template<typename T> class C : public T 
{ 
    decltype(std::declval<T>().foo()) footype; 
}; 

declval रिटर्न एक T&&। या यदि foo rvalue-रेफरी क्वालिफायर के साथ अतिभारित किया जा सकता है, और आप आप foo की lvalue अधिभार प्राप्त बीमा करने के लिए करना चाहते हैं: इस उदाहरण में

decltype(std::declval<T&>().foo()) footype; 

declval एक T& देता है।

((T*)nullptr)-> समाधान की तरह, std::declvalT पर कोई आवश्यकता नहीं रखता है।

+1

पेडेंटिक 'std :: declval' में नहीं है, प्रति एफडीआईएस 20.2 [उपयोगिता]/2 – Cubbi

+0

अच्छी पकड़! मैंने जवाब में हेडर बदल दिया है। धन्यवाद! –

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