2011-12-21 7 views
42

क्या यह लैम्ब्डा रिकर्सन मान्य है?क्या यह लैम्बडा के लिए मान्य है, अनिवार्य रूप से, अपने आप को बंद कर दें?

#include <functional> 
#include <iostream> 

int main() { 
    std::function<int(int)> g = [&g](int k) { 
     return (k ? k * g(k-1) : 1); 
    }; 

    std::cout << g(10); // 3628800 
} 

यह appears to compile and run ok, लेकिन मैं एक ही बयान है कि मैं इसे आरंभ में g से अधिक बंद करने के बारे में घबरा रहा हूँ। 1-10 के पैमाने पर सख्त वैधता ...?

+0

सी # में, जो संकलित नहीं होगा; आपको इसे दो बयानों में तोड़ना होगा। – SLaks

+2

सी ++ 0x उदाहरण [यहां] (http://zamjad.wordpress.com/2011/09/22/c-recursive-lambda-functions/) इसे 2 कथन में तोड़ दें, लेकिन क्यों नहीं समझाते। – Joe

+0

मुझे लगता है कि यह अपरिभाषित व्यवहार है। Lambdas रिकर्सन के लिए डिज़ाइन नहीं किया गया है क्योंकि यह एक अनाम कार्य है, क्या मैं सही हूँ? – Hauleth

उत्तर

20

बिंदु है जिस पर आप संदर्भ द्वारा g पर कब्जा, यह घोषित किया गया है, इसलिए नाम उपयोग के लिए उपलब्ध है:

3.3.2/1 एक नाम के लिए घोषणा की बात अपने के तुरंत बाद है पूरा declarator (खण्ड 8) और उसके प्रारंभकर्ता

आप सीमित विधियों में वस्तुओं का उपयोग करने के पहले वे initialised कर रहे हैं अनुमति दी जाती है इससे पहले कि - मूल रूप से, कुछ भी है कि मूल्य पर निर्भर नहीं करता ठीक है:

3.8/6 किसी ऑब्जेक्ट के जीवनकाल से पहले शुरू हो गया है लेकिन ऑब्जेक्ट पर कब्जा करने के बाद आवंटित किया गया है [...] मूल वस्तु को संदर्भित करने वाला कोई भी ग्लूबल उपयोग किया जा सकता है लेकिन केवल तरीकों से सीमित है। [...] glvalue के गुणों का उपयोग जो उसके मूल्य पर निर्भर नहीं है अच्छी तरह से परिभाषित है।

तो मेरी समझ से, आप जो कर रहे हैं वह अच्छी तरह से परिभाषित है।

(हालांकि, अल्ट्रापेडेंटिक होने के नाते, मुझे नहीं लगता कि यह निर्दिष्ट किया गया है कि स्वचालित ऑब्जेक्ट के लिए संग्रहण आवंटित किया जाता है, और 8.3.2/5 कहता है कि परिभाषित किए बिना "एक वैध ऑब्जेक्ट को संदर्भित करने के लिए एक संदर्भ प्रारंभ किया जाएगा" "मान्य" है, इसलिए तर्क देने का दायरा है कि यह अच्छी तरह से परिभाषित नहीं है)।

+0

मैं इस बात से सहमत हूं कि किसी संदर्भ को बाध्य करने के लिए एक लालसा-से-रावल्यू रूपांतरण की आवश्यकता नहीं होनी चाहिए, लेकिन इस क्षेत्र में भाषा के अर्थशास्त्र की व्याख्या करने के लिए _very_ कठिन हैं। :(यहां तक ​​कि सी ++ के लिए भी! –

+0

ठीक है, मुझे लगता है कि यह मुझे संतुष्ट करता है! –

+0

मैं इसे पोस्ट करने वाला था: पी किसी भी फ़ंक्शन परिभाषा की तरह, कोड को तब निष्पादित नहीं किया जाता है; 'g' को इसके लिए कोई मान नहीं चाहिए कारण 'के' को परिभाषा के परिप्रेक्ष्य से मूल्य की आवश्यकता नहीं है।' जी 'का उपयोग '[& g]' के साथ किया जा रहा है, लेकिन यह केवल भविष्य के कार्य का पता ले रहा है। और उस बिंदु पर 'g' मौजूद है क्योंकि घोषणाएं असाइनमेंट से पहले होती हैं। –

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