2016-07-12 11 views
37

निम्नलिखित पर विचार करें:ऑटो रिटर्न प्रकार कटौती कार्य पूरी तरह परिभाषित प्रकारों के साथ क्यों नहीं करता है?

template<typename Der> 
struct Base { 
    // NOTE: if I replace the decltype(...) below with auto, code compiles 
    decltype(&Der::operator()) getCallOperator() const { 
     return &Der::operator(); 
    } 
}; 

struct Foo : Base<Foo> { 
    double operator()(int, int) const { 
     return 0.0; 
    } 
}; 

int main() { 
    Foo f; 
    auto callOp = f.getCallOperator(); 
} 

मैं व्युत्पन्न वर्ग में operator() के हस्ताक्षर के आधार पर एक वापसी प्रकार के साथ CRTP आधार वर्ग में एक सदस्य समारोह बनाना चाहते हैं। हालांकि संकलन करने में विफल रहता है; operator()Foo में सदस्य फ़ंक्शन दिखाई नहीं दे रहा है। मुझे लगता है कि ऐसा इसलिए है क्योंकि Foo से पहले बेस क्लास टेम्पलेट को तत्काल परिभाषित किया गया है।

आश्चर्य की बात है, अगर मैं वापसी प्रकार के लिए auto डालता हूं तो यह संकलित करता है। मुझे लगता है कि auto संकलक को फ़ंक्शन बॉडी से वापसी प्रकार को कम कर देगा और असफल हो जाएगा - क्योंकि शरीर पूरी तरह परिभाषित Foo प्रकार का उपयोग नहीं करता है।

यह व्यवहार दोनों MSVC 2015.3 और बजना 3.8 के लिए एक ही

क्यों कोड auto के साथ काम करने शुरू किया है? क्या auto किसी भी प्रकार की कटौती को तत्काल "देरी" करता है? या एक हाथ से लिखित वापसी प्रकार अभिव्यक्ति की तुलना में एक अलग संदर्भ का उपयोग करें?

+5

अच्छा सवाल। Upvoted। –

+0

[सीआरटीपी और सी ++ 1y रिटर्न टाइप कटौती] का संभावित डुप्लिकेट (http://stackoverflow.com/questions/19892479/crtp-and-c1y-return-type-deduction) – Holt

+0

यह वही समस्या है लेकिन प्रश्न और उत्तर दृष्टिकोण यह थोड़ा अलग कोण से। यहां हमारे पास "ऑटो कटौती अलग कैसे है", लिंक किए गए प्रश्न और इसका उत्तर "हाथ से लिखित अभिव्यक्ति कार्य कैसे कर सकता है" के बारे में अधिक है। हालांकि यह अभी भी डुप्लिकेट के रूप में योग्य हो सकता है ... –

उत्तर

24

आपका अनुमान सही है। एक कटौती वापसी प्रकार वास्तव में तब तक नहीं लिया जाता है जब तक कि फ़ंक्शन के हस्ताक्षर की आवश्यकता न हो। इसका मतलब यह है कि इसे कॉल के संदर्भ में getCallOperator पर घटाया जाएगा, जिस बिंदु पर Foo पूरी तरह से परिभाषित किया गया है।

यह 7.1.6.4p12 में निर्दिष्ट किया जाता: अपनी घोषित प्रकार में एक प्लेसहोल्डर के साथ एक समारोह टेम्पलेट के लिए

वापसी प्रकार कटौती तब होता है जब परिभाषा instantiated है, भले ही समारोह शरीर एक साथ एक वापसी कथन शामिल गैर-प्रकार-निर्भर ऑपरेंड।

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

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